@@ -16,7 +16,7 @@ import cpp
1616import semmle.code.cpp.controlflow.IRGuards
1717import semmle.code.cpp.security.FlowSources as FS
1818import semmle.code.cpp.dataflow.new.TaintTracking
19- import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
19+ import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
2020import ImproperArrayIndexValidation:: PathGraph
2121
2222predicate isFlowSource ( FS:: FlowSource source , string sourceType ) {
@@ -39,6 +39,17 @@ predicate guardChecks(IRGuardCondition g, Expr e, boolean branch) {
3939 )
4040}
4141
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+
4253module ImproperArrayIndexValidationConfig implements DataFlow:: ConfigSig {
4354 predicate isSource ( DataFlow:: Node source ) { isFlowSource ( source , _) }
4455
@@ -51,7 +62,8 @@ module ImproperArrayIndexValidationConfig implements DataFlow::ConfigSig {
5162 predicate isSink ( DataFlow:: Node sink ) {
5263 exists ( ArrayExpr arrayExpr , VariableAccess offsetExpr |
5364 offsetExpr = arrayExpr .getArrayOffset ( ) and
54- sink .asExpr ( ) = offsetExpr
65+ sink .asExpr ( ) = offsetExpr and
66+ not offsetIsAlwaysInBounds ( arrayExpr , offsetExpr )
5567 )
5668 }
5769}
0 commit comments