-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathBounded.qll
More file actions
57 lines (54 loc) · 1.96 KB
/
Bounded.qll
File metadata and controls
57 lines (54 loc) · 1.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/**
* This file provides the `bounded` predicate that is used in `cpp/uncontrolled-arithmetic`,
* `cpp/tainted-arithmetic` and `cpp/uncontrolled-allocation-size`.
*/
private import cpp
private import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
/**
* An operand `operand` of a bitwise and expression `andExpr` (i.e., `andExpr` is either a
* `BitwiseAndExpr` or an `AssignAndExpr`) is upper bounded by some number that is less than the
* maximum integer allowed by the result type of `andExpr`.
*/
pragma[inline]
private predicate boundedBitwiseAnd(Expr operand, Expr andExpr) {
upperBound(operand.getFullyConverted()) < exprMaxVal(andExpr.getFullyConverted())
}
/**
* Holds if `e` is an arithmetic expression that cannot overflow, or if `e` is an operation that
* may greatly reduce the range of possible values.
*/
predicate bounded(Expr e) {
// There can be two separate reasons for `convertedExprMightOverflow` not holding:
// 1. `e` really cannot overflow.
// 2. `e` isn't analyzable.
// If we didn't rule out case 2 we would declare anything that isn't analyzable as bounded.
(
e instanceof UnaryArithmeticOperation or
e instanceof BinaryArithmeticOperation or
e instanceof AssignArithmeticOperation
) and
not convertedExprMightOverflow(e)
or
// Optimistically assume that the following operations always yields a much smaller value.
e instanceof RemExpr
or
e instanceof DivExpr
or
e instanceof RShiftExpr
or
exists(BitwiseAndExpr andExpr |
e = andExpr and boundedBitwiseAnd(andExpr.getAnOperand(), andExpr)
)
or
// For the assignment variant of the operations we place the barrier on the assigned lvalue.
e = any(AssignRemExpr rem).getLValue()
or
e = any(AssignDivExpr div).getLValue()
or
e = any(AssignRShiftExpr div).getLValue()
or
exists(AssignAndExpr andExpr |
e = andExpr.getLValue() and boundedBitwiseAnd(andExpr.getRValue(), andExpr)
)
}