Skip to content

Commit a5ccd6a

Browse files
authored
Merge pull request #7521 from rdmarsh2/rdmarsh2/cpp/use-guards-in-overflow
2 parents 3b0d55e + 4322a39 commit a5ccd6a

File tree

2 files changed

+12
-57
lines changed
  • cpp/ql
    • lib/semmle/code/cpp/security
    • test/query-tests/Security/CWE/CWE-190/semmle/ArithmeticUncontrolled

2 files changed

+12
-57
lines changed

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

Lines changed: 4 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -9,60 +9,24 @@ import semmle.code.cpp.controlflow.Dominance
99
private import semmle.code.cpp.valuenumbering.GlobalValueNumbering
1010
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
1111
import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
12+
import semmle.code.cpp.controlflow.Guards
1213

1314
/**
1415
* Holds if the value of `use` is guarded using `abs`.
1516
*/
1617
predicate guardedAbs(Operation e, Expr use) {
1718
exists(FunctionCall fc | fc.getTarget().getName() = ["abs", "labs", "llabs", "imaxabs"] |
1819
fc.getArgument(0).getAChild*() = use and
19-
guardedLesser(e, fc)
20+
exists(GuardCondition c | c.ensuresLt(fc, _, _, e.getBasicBlock(), true))
2021
)
2122
}
2223

23-
/**
24-
* Gets the position of `stmt` in basic block `block` (this is a thin layer
25-
* over `BasicBlock.getNode`, intended to improve performance).
26-
*/
27-
pragma[noinline]
28-
private int getStmtIndexInBlock(BasicBlock block, Stmt stmt) { block.getNode(result) = stmt }
29-
30-
pragma[inline]
31-
private predicate stmtDominates(Stmt dominator, Stmt dominated) {
32-
// In same block
33-
exists(BasicBlock block, int dominatorIndex, int dominatedIndex |
34-
dominatorIndex = getStmtIndexInBlock(block, dominator) and
35-
dominatedIndex = getStmtIndexInBlock(block, dominated) and
36-
dominatedIndex >= dominatorIndex
37-
)
38-
or
39-
// In (possibly) different blocks
40-
bbStrictlyDominates(dominator.getBasicBlock(), dominated.getBasicBlock())
41-
}
42-
4324
/**
4425
* Holds if the value of `use` is guarded to be less than something, and `e`
4526
* is in code controlled by that guard (where the guard condition held).
4627
*/
47-
pragma[nomagic]
4828
predicate guardedLesser(Operation e, Expr use) {
49-
exists(IfStmt c, RelationalOperation guard |
50-
use = guard.getLesserOperand().getAChild*() and
51-
guard = c.getControllingExpr().getAChild*() and
52-
stmtDominates(c.getThen(), e.getEnclosingStmt())
53-
)
54-
or
55-
exists(Loop c, RelationalOperation guard |
56-
use = guard.getLesserOperand().getAChild*() and
57-
guard = c.getControllingExpr().getAChild*() and
58-
stmtDominates(c.getStmt(), e.getEnclosingStmt())
59-
)
60-
or
61-
exists(ConditionalExpr c, RelationalOperation guard |
62-
use = guard.getLesserOperand().getAChild*() and
63-
guard = c.getCondition().getAChild*() and
64-
c.getThen().getAChild*() = e
65-
)
29+
exists(GuardCondition c | c.ensuresLt(use, _, _, e.getBasicBlock(), true))
6630
or
6731
guardedAbs(e, use)
6832
}
@@ -71,25 +35,8 @@ predicate guardedLesser(Operation e, Expr use) {
7135
* Holds if the value of `use` is guarded to be greater than something, and `e`
7236
* is in code controlled by that guard (where the guard condition held).
7337
*/
74-
pragma[nomagic]
7538
predicate guardedGreater(Operation e, Expr use) {
76-
exists(IfStmt c, RelationalOperation guard |
77-
use = guard.getGreaterOperand().getAChild*() and
78-
guard = c.getControllingExpr().getAChild*() and
79-
stmtDominates(c.getThen(), e.getEnclosingStmt())
80-
)
81-
or
82-
exists(Loop c, RelationalOperation guard |
83-
use = guard.getGreaterOperand().getAChild*() and
84-
guard = c.getControllingExpr().getAChild*() and
85-
stmtDominates(c.getStmt(), e.getEnclosingStmt())
86-
)
87-
or
88-
exists(ConditionalExpr c, RelationalOperation guard |
89-
use = guard.getGreaterOperand().getAChild*() and
90-
guard = c.getCondition().getAChild*() and
91-
c.getThen().getAChild*() = e
92-
)
39+
exists(GuardCondition c | c.ensuresLt(use, _, _, e.getBasicBlock(), false))
9340
or
9441
guardedAbs(e, use)
9542
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,11 @@ void moreTests() {
157157
r = r - 100; // BAD
158158
}
159159
}
160+
161+
void guarded_test(unsigned p) {
162+
unsigned data = (unsigned int)rand();
163+
if (p >= data) {
164+
return;
165+
}
166+
unsigned z = data - p; // GOOD
167+
}

0 commit comments

Comments
 (0)