@@ -16,7 +16,7 @@ import cpp
16
16
import semmle.code.cpp.controlflow.IRGuards
17
17
import semmle.code.cpp.security.FlowSources as FS
18
18
import semmle.code.cpp.dataflow.new.TaintTracking
19
- import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
19
+ import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
20
20
import ImproperArrayIndexValidation:: PathGraph
21
21
22
22
predicate isFlowSource ( FS:: FlowSource source , string sourceType ) {
@@ -39,6 +39,17 @@ predicate guardChecks(IRGuardCondition g, Expr e, boolean branch) {
39
39
)
40
40
}
41
41
42
+ /**
43
+ * Holds if `arrayExpr` accesses an `ArrayType` with a constant size `N`, and
44
+ * the value of `offsetExpr` is known to be smaller than `N`.
45
+ */
46
+ predicate offsetIsAlwaysInBounds ( ArrayExpr arrayExpr , VariableAccess offsetExpr ) {
47
+ exists ( ArrayType arrayType |
48
+ arrayType = arrayExpr .getArrayBase ( ) .getUnspecifiedType ( ) and
49
+ arrayType .getArraySize ( ) > upperBound ( offsetExpr .getFullyConverted ( ) )
50
+ )
51
+ }
52
+
42
53
module ImproperArrayIndexValidationConfig implements DataFlow:: ConfigSig {
43
54
predicate isSource ( DataFlow:: Node source ) { isFlowSource ( source , _) }
44
55
@@ -51,7 +62,8 @@ module ImproperArrayIndexValidationConfig implements DataFlow::ConfigSig {
51
62
predicate isSink ( DataFlow:: Node sink ) {
52
63
exists ( ArrayExpr arrayExpr , VariableAccess offsetExpr |
53
64
offsetExpr = arrayExpr .getArrayOffset ( ) and
54
- sink .asExpr ( ) = offsetExpr
65
+ sink .asExpr ( ) = offsetExpr and
66
+ not offsetIsAlwaysInBounds ( arrayExpr , offsetExpr )
55
67
)
56
68
}
57
69
}
0 commit comments