findEFIVariables: Added metadata, fixed logic by matching on the call and not the expr

This commit is contained in:
Giulio De Pasquale 2023-02-19 21:15:12 -08:00
parent 4368e65b49
commit 5dec732ae5

View File

@ -1,3 +1,16 @@
/**
* @name Find uses of EFI variables
* @description Finds all uses of EFI variables in a C/C++ codebase.
* @kind problem
* @problem.severity warning
* @id cpp/find-uses-of-efi-variables
* @tags security
* efi
* external interface
* @precision low
* @queryLanguages cpp
*/
import cpp
import semmle.code.cpp.security.FlowSources
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
@ -18,25 +31,23 @@ class EFIVarPtrFunction extends PointerFieldAccess {
}
predicate callHandlesEFIVariable(Expr e, Call c) {
exists(Call x, PointerFieldAccess fa |
exists(Call x |
// in case it is just a normal function call
x.getParent() = e and x.getTarget() instanceof EFIVarFunction
(x = c and x.getParent() = e and x.getTarget() instanceof EFIVarFunction)
)
or
exists(VariableCall vc, PointerFieldAccess fa |
// in case the function call is actually a pointer field access, the function name will be the name of the field itself
c = x and
c instanceof VariableCall and
c = vc and
vc.getParent() = e and
fa instanceof EFIVarPtrFunction and
x.getParent() = e and
c.(VariableCall).getVariable() = fa.getTarget()
vc.getVariable() = fa.getTarget()
)
}
class EFIVar extends Variable {
EFIVar() { exists(Expr e | callHandlesEFIVariable(e, _) and e.(Access).getTarget() = this) }
EFIVar() { exists(Call c | callHandlesEFIVariable(_, c) and c.getAnArgument().(Access).getTarget() = this) }
}
from Expr e, Call c, Variable v
where
callHandlesEFIVariable(e, c) and
e.(Access).getTarget() = v
from EFIVar v
select v, "This expression uses EFI variables"