@@ -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+
6891class 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