Skip to content

Commit e1028a2

Browse files
authored
Merge pull request github#5667 from MathiasVP/use-range-analysis-in-overflow
C++: Use range analysis in Overflow.qll
2 parents 605f28f + 7fbc623 commit e1028a2

File tree

5 files changed

+19
-7
lines changed

5 files changed

+19
-7
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
lgtm
2+
* The queries cpp/tainted-arithmetic, cpp/uncontrolled-arithmetic, and cpp/arithmetic-with-extreme-values have been improved to produce fewer false positives.

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

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
import cpp
77
import semmle.code.cpp.controlflow.Dominance
8+
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
9+
import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
810

911
/**
1012
* Holds if the value of `use` is guarded using `abs`.
@@ -94,9 +96,15 @@ predicate guardedGreater(Operation e, Expr use) {
9496
VariableAccess varUse(LocalScopeVariable v) { result = v.getAnAccess() }
9597

9698
/**
97-
* Holds if `e` is not guarded against overflow by `use`.
99+
* Holds if `e` potentially overflows and `use` is an operand of `e` that is not guarded.
98100
*/
99101
predicate missingGuardAgainstOverflow(Operation e, VariableAccess use) {
102+
(
103+
convertedExprMightOverflowPositively(e)
104+
or
105+
// Ensure that the predicate holds when range analysis cannot determine an upper bound
106+
upperBound(e.getFullyConverted()) = exprMaxVal(e.getFullyConverted())
107+
) and
100108
use = e.getAnOperand() and
101109
exists(LocalScopeVariable v | use.getTarget() = v |
102110
// overflow possible if large
@@ -115,9 +123,15 @@ predicate missingGuardAgainstOverflow(Operation e, VariableAccess use) {
115123
}
116124

117125
/**
118-
* Holds if `e` is not guarded against underflow by `use`.
126+
* Holds if `e` potentially underflows and `use` is an operand of `e` that is not guarded.
119127
*/
120128
predicate missingGuardAgainstUnderflow(Operation e, VariableAccess use) {
129+
(
130+
convertedExprMightOverflowNegatively(e)
131+
or
132+
// Ensure that the predicate holds when range analysis cannot determine a lower bound
133+
lowerBound(e.getFullyConverted()) = exprMinVal(e.getFullyConverted())
134+
) and
121135
use = e.getAnOperand() and
122136
exists(LocalScopeVariable v | use.getTarget() = v |
123137
// underflow possible if use is left operand and small

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,4 @@
44
| test.c:59:3:59:5 | sc6 | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:58:9:58:16 | 127 | Extreme value |
55
| test.c:63:3:63:5 | sc8 | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test.c:62:9:62:16 | - ... | Extreme value |
66
| test.c:75:3:75:5 | sc1 | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:74:9:74:16 | 127 | Extreme value |
7-
| test.c:76:3:76:5 | sc1 | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:74:9:74:16 | 127 | Extreme value |
87
| test.c:124:9:124:9 | x | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:118:17:118:23 | 2147483647 | Extreme value |

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ void test_negatives() {
7373

7474
sc1 = CHAR_MAX;
7575
sc1 += 0; // GOOD [FALSE POSITIVE]
76-
sc1 += -1; // GOOD [FALSE POSITIVE]
76+
sc1 += -1; // GOOD
7777
sc2 = CHAR_MIN;
7878
sc2 += -1; // BAD [NOT DETECTED]
7979
sc3 = CHAR_MIN;

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
| test2.cpp:14:11:14:11 | v | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
22
| test2.cpp:14:11:14:11 | v | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
3-
| test3.c:15:10:15:10 | x | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test3.c:11:15:11:18 | argv | User-provided value |
4-
| test3.c:15:14:15:14 | y | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test3.c:11:15:11:18 | argv | User-provided value |
5-
| test3.c:15:18:15:18 | z | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test3.c:11:15:11:18 | argv | User-provided value |
63
| test5.cpp:17:6:17:18 | call to getTaintedInt | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
74
| test5.cpp:19:6:19:6 | y | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
85
| test5.cpp:19:6:19:6 | y | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test5.cpp:9:7:9:9 | buf | User-provided value |

0 commit comments

Comments
 (0)