Skip to content

Commit a2cdb9c

Browse files
committed
C++: Use range analysis at the sink to exclude trivial FPs.
1 parent c3d9ea1 commit a2cdb9c

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

cpp/ql/src/Security/CWE/CWE-129/ImproperArrayIndexValidation.ql

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import cpp
1616
import semmle.code.cpp.controlflow.IRGuards
1717
import semmle.code.cpp.security.FlowSources as FS
1818
import semmle.code.cpp.dataflow.new.TaintTracking
19-
import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
19+
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
2020
import ImproperArrayIndexValidation::PathGraph
2121

2222
predicate 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+
4253
module 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

Comments
 (0)