Skip to content

Commit f4a1b41

Browse files
committed
C++: Correct hasUpperBoundsCheck.
1 parent 26ed560 commit f4a1b41

File tree

4 files changed

+27
-9
lines changed

4 files changed

+27
-9
lines changed

cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,17 @@ private predicate writesVariable(StoreInstruction store, Variable var) {
130130
}
131131

132132
/**
133-
* A variable that has any kind of upper-bound check anywhere in the program
133+
* A variable that has any kind of upper-bound check anywhere in the program. This is
134+
* biased towards being inclusive because there are a lot of valid ways of doing an
135+
* upper bounds checks if we don't consider where it occurs, for example:
136+
* ```
137+
* if (x < 10) { sink(x); }
138+
*
139+
* if (10 > y) { sink(y); }
140+
*
141+
* if (z > 10) { z = 10; }
142+
* sink(z);
143+
* ```
134144
*/
135145
// TODO: This coarse overapproximation, ported from the old taint tracking
136146
// library, could be replaced with an actual semantic check that a particular
@@ -139,10 +149,10 @@ private predicate writesVariable(StoreInstruction store, Variable var) {
139149
// previously suppressed by this predicate by coincidence.
140150
private predicate hasUpperBoundsCheck(Variable var) {
141151
exists(RelationalOperation oper, VariableAccess access |
142-
oper.getLeftOperand() = access and
152+
oper.getAnOperand() = access and
143153
access.getTarget() = var and
144154
// Comparing to 0 is not an upper bound check
145-
not oper.getRightOperand().getValue() = "0"
155+
not oper.getAnOperand().getValue() = "0"
146156
)
147157
}
148158

cpp/ql/src/semmle/code/cpp/security/TaintTrackingImpl.qll

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -328,14 +328,24 @@ GlobalOrNamespaceVariable globalVarFromId(string id) {
328328
}
329329

330330
/**
331-
* A variable that has any kind of upper-bound check anywhere in the program
331+
* A variable that has any kind of upper-bound check anywhere in the program. This is
332+
* biased towards being inclusive because there are a lot of valid ways of doing an
333+
* upper bounds checks if we don't consider where it occurs, for example:
334+
* ```
335+
* if (x < 10) { sink(x); }
336+
*
337+
* if (10 > y) { sink(y); }
338+
*
339+
* if (z > 10) { z = 10; }
340+
* sink(z);
341+
* ```
332342
*/
333343
private predicate hasUpperBoundsCheck(Variable var) {
334344
exists(RelationalOperation oper, VariableAccess access |
335-
oper.getLeftOperand() = access and
345+
oper.getAnOperand() = access and
336346
access.getTarget() = var and
337347
// Comparing to 0 is not an upper bound check
338-
not oper.getRightOperand().getValue() = "0"
348+
not oper.getAnOperand().getValue() = "0"
339349
)
340350
}
341351

cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/TaintedAllocationSize.expected

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,3 @@
1212
| test.cpp:134:10:134:27 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:132:19:132:24 | call to getenv | user input (getenv) |
1313
| test.cpp:142:4:142:9 | call to malloc | This allocation size is derived from $@ and might overflow | test.cpp:138:19:138:24 | call to getenv | user input (getenv) |
1414
| test.cpp:142:11:142:28 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:138:19:138:24 | call to getenv | user input (getenv) |
15-
| test.cpp:169:4:169:9 | call to malloc | This allocation size is derived from $@ and might overflow | test.cpp:165:19:165:24 | call to getenv | user input (getenv) |
16-
| test.cpp:169:11:169:28 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:165:19:165:24 | call to getenv | user input (getenv) |

cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ void more_bounded_tests() {
166166

167167
if ((100 > size) && (0 < size))
168168
{
169-
malloc(size * sizeof(int)); // GOOD [FALSE POSITIVE]
169+
malloc(size * sizeof(int)); // GOOD
170170
}
171171
}
172172

0 commit comments

Comments
 (0)