@@ -65,6 +65,29 @@ Expr asSinkExpr(DataFlow::Node node) {
65
65
.getUnconvertedResultExpression ( )
66
66
}
67
67
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
+
68
91
class TaintedPathConfiguration extends TaintTracking:: Configuration {
69
92
TaintedPathConfiguration ( ) { this = "TaintedPathConfiguration" }
70
93
@@ -80,6 +103,12 @@ class TaintedPathConfiguration extends TaintTracking::Configuration {
80
103
81
104
override predicate isSanitizer ( DataFlow:: Node node ) {
82
105
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
+ )
83
112
}
84
113
85
114
predicate hasFilteredFlowPath ( DataFlow:: PathNode source , DataFlow:: PathNode sink ) {
0 commit comments