C++: Introduce the coarse upper bound check from default taint tracking

This commit is contained in:
Jeroen Ketema
2022-11-30 21:08:36 +01:00
parent d3cccca7f1
commit 3dfe18b565

View File

@@ -65,6 +65,29 @@ Expr asSinkExpr(DataFlow::Node node) {
.getUnconvertedResultExpression()
}
/**
* Holds for a variable that has any kind of upper-bound check anywhere in the program.
* This is biased towards being inclusive and being a coarse overapproximation because
* there are a lot of valid ways of doing an upper bounds checks if we don't consider
* where it occurs, for example:
* ```cpp
* if (x < 10) { sink(x); }
*
* if (10 > y) { sink(y); }
*
* if (z > 10) { z = 10; }
* sink(z);
* ```
*/
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"
)
}
class TaintedPathConfiguration extends TaintTracking::Configuration {
TaintedPathConfiguration() { this = "TaintedPathConfiguration" }
@@ -80,6 +103,12 @@ class TaintedPathConfiguration extends TaintTracking::Configuration {
override predicate isSanitizer(DataFlow::Node node) {
node.asExpr().(Call).getTarget().getUnspecifiedType() instanceof ArithmeticType
or
exists(LoadInstruction load, Variable checkedVar |
load = node.asInstruction() and
checkedVar = load.getSourceAddress().(VariableAddressInstruction).getAstVariable() and
hasUpperBoundsCheck(checkedVar)
)
}
predicate hasFilteredFlowPath(DataFlow::PathNode source, DataFlow::PathNode sink) {