mirror of
https://github.com/github/codeql.git
synced 2026-05-04 13:15:21 +02:00
C++: Use a 'TaintTracking::Configuration' for 'cpp/overflow-destination'.
This commit is contained in:
@@ -14,7 +14,10 @@
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.security.TaintTracking
|
||||
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||
import semmle.code.cpp.controlflow.IRGuards
|
||||
import semmle.code.cpp.security.FlowSources
|
||||
import DataFlow::PathGraph
|
||||
|
||||
/**
|
||||
* Holds if `fc` is a call to a copy operation where the size argument contains
|
||||
@@ -45,9 +48,49 @@ predicate sourceSized(FunctionCall fc, Expr src) {
|
||||
)
|
||||
}
|
||||
|
||||
from FunctionCall fc, Expr vuln, Expr taintSource
|
||||
predicate readsVariable(LoadInstruction load, Variable var) {
|
||||
load.getSourceAddress().(VariableAddressInstruction).getASTVariable() = var
|
||||
}
|
||||
|
||||
predicate hasUpperBoundsCheck(Variable var) {
|
||||
exists(RelationalOperation oper, VariableAccess access |
|
||||
oper.getAnOperand() = access and
|
||||
access.getTarget() = var and
|
||||
// Comparing to 0 is not an upper bound check
|
||||
not oper.getAnOperand().getValue() = "0"
|
||||
)
|
||||
}
|
||||
|
||||
predicate nodeIsBarrierEqualityCandidate(DataFlow::Node node, Operand access, Variable checkedVar) {
|
||||
readsVariable(node.asInstruction(), checkedVar) and
|
||||
any(IRGuardCondition guard).ensuresEq(access, _, _, node.asInstruction().getBlock(), true)
|
||||
}
|
||||
|
||||
class OverflowDestinationConfig extends TaintTracking::Configuration {
|
||||
OverflowDestinationConfig() { this = "OverflowDestinationConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof FlowSource }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sourceSized(_, sink.asExpr()) }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
exists(Variable checkedVar |
|
||||
readsVariable(node.asInstruction(), checkedVar) and
|
||||
hasUpperBoundsCheck(checkedVar)
|
||||
)
|
||||
or
|
||||
exists(Variable checkedVar, Operand access |
|
||||
readsVariable(access.getDef(), checkedVar) and
|
||||
nodeIsBarrierEqualityCandidate(node, access, checkedVar)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
from
|
||||
FunctionCall fc, OverflowDestinationConfig conf, DataFlow::PathNode source,
|
||||
DataFlow::PathNode sink
|
||||
where
|
||||
sourceSized(fc, vuln) and
|
||||
tainted(taintSource, vuln)
|
||||
conf.hasFlowPath(source, sink) and
|
||||
sourceSized(fc, sink.getNode().asExpr())
|
||||
select fc,
|
||||
"To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size."
|
||||
|
||||
Reference in New Issue
Block a user