Skip to content

Commit 3dfe18b

Browse files
committed
C++: Introduce the coarse upper bound check from default taint tracking
1 parent d3cccca commit 3dfe18b

File tree

1 file changed

+29
-0
lines changed

1 file changed

+29
-0
lines changed

cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,29 @@ Expr asSinkExpr(DataFlow::Node node) {
6565
.getUnconvertedResultExpression()
6666
}
6767

68+
/**
69+
* Holds for a variable that has any kind of upper-bound check anywhere in the program.
70+
* This is biased towards being inclusive and being a coarse overapproximation because
71+
* there are a lot of valid ways of doing an upper bounds checks if we don't consider
72+
* where it occurs, for example:
73+
* ```cpp
74+
* if (x < 10) { sink(x); }
75+
*
76+
* if (10 > y) { sink(y); }
77+
*
78+
* if (z > 10) { z = 10; }
79+
* sink(z);
80+
* ```
81+
*/
82+
predicate hasUpperBoundsCheck(Variable var) {
83+
exists(RelationalOperation oper, VariableAccess access |
84+
oper.getAnOperand() = access and
85+
access.getTarget() = var and
86+
// Comparing to 0 is not an upper bound check
87+
not oper.getAnOperand().getValue() = "0"
88+
)
89+
}
90+
6891
class TaintedPathConfiguration extends TaintTracking::Configuration {
6992
TaintedPathConfiguration() { this = "TaintedPathConfiguration" }
7093

@@ -80,6 +103,12 @@ class TaintedPathConfiguration extends TaintTracking::Configuration {
80103

81104
override predicate isSanitizer(DataFlow::Node node) {
82105
node.asExpr().(Call).getTarget().getUnspecifiedType() instanceof ArithmeticType
106+
or
107+
exists(LoadInstruction load, Variable checkedVar |
108+
load = node.asInstruction() and
109+
checkedVar = load.getSourceAddress().(VariableAddressInstruction).getAstVariable() and
110+
hasUpperBoundsCheck(checkedVar)
111+
)
83112
}
84113

85114
predicate hasFilteredFlowPath(DataFlow::PathNode source, DataFlow::PathNode sink) {

0 commit comments

Comments
 (0)