|
15 | 15 |
|
16 | 16 | import cpp
|
17 | 17 | import codingstandards.cpp.autosar
|
18 |
| -import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis |
| 18 | +import codingstandards.cpp.Overflow |
19 | 19 | import semmle.code.cpp.controlflow.Guards
|
20 |
| -import semmle.code.cpp.dataflow.TaintTracking |
21 | 20 | import semmle.code.cpp.valuenumbering.GlobalValueNumbering
|
22 | 21 |
|
23 |
| -/** |
24 |
| - * A `BinaryArithmeticOperation` which may overflow and is a potentially interesting case to review |
25 |
| - * that is not covered by other queries for this rule. |
26 |
| - */ |
27 |
| -class InterestingBinaryOverflowingExpr extends BinaryArithmeticOperation { |
28 |
| - InterestingBinaryOverflowingExpr() { |
29 |
| - // Might overflow or underflow |
30 |
| - ( |
31 |
| - exprMightOverflowNegatively(this) |
32 |
| - or |
33 |
| - exprMightOverflowPositively(this) |
34 |
| - ) and |
35 |
| - not this.isAffectedByMacro() and |
36 |
| - // Ignore pointer arithmetic |
37 |
| - not this instanceof PointerArithmeticOperation and |
38 |
| - // Covered by `IntMultToLong.ql` instead |
39 |
| - not this instanceof MulExpr and |
40 |
| - // Not covered by this query - overflow/underflow in division is rare |
41 |
| - not this instanceof DivExpr |
42 |
| - } |
43 |
| - |
44 |
| - /** |
45 |
| - * Get a `GVN` which guards this expression which may overflow. |
46 |
| - */ |
47 |
| - GVN getAGuardingGVN() { |
48 |
| - exists(GuardCondition gc, Expr e | |
49 |
| - not gc = getABadOverflowCheck() and |
50 |
| - TaintTracking::localTaint(DataFlow::exprNode(e), DataFlow::exprNode(gc.getAChild*())) and |
51 |
| - gc.controls(this.getBasicBlock(), _) and |
52 |
| - result = globalValueNumber(e) |
53 |
| - ) |
54 |
| - } |
55 |
| - |
56 |
| - /** |
57 |
| - * Identifies a bad overflow check for this overflow expression. |
58 |
| - */ |
59 |
| - GuardCondition getABadOverflowCheck() { |
60 |
| - exists(AddExpr ae, RelationalOperation relOp | |
61 |
| - this = ae and |
62 |
| - result = relOp and |
63 |
| - // Looking for this pattern: |
64 |
| - // if (x + y > x) |
65 |
| - // use(x + y) |
66 |
| - // |
67 |
| - globalValueNumber(relOp.getAnOperand()) = globalValueNumber(ae) and |
68 |
| - globalValueNumber(relOp.getAnOperand()) = globalValueNumber(ae.getAnOperand()) |
69 |
| - | |
70 |
| - // Signed overflow checks are insufficient |
71 |
| - ae.getUnspecifiedType().(IntegralType).isSigned() |
72 |
| - or |
73 |
| - // Unsigned overflow checks can still be bad, if the result is promoted. |
74 |
| - forall(Expr op | op = ae.getAnOperand() | op.getType().getSize() < any(IntType i).getSize()) and |
75 |
| - // Not explicitly converted to a smaller type before the comparison |
76 |
| - not ae.getExplicitlyConverted().getType().getSize() < any(IntType i).getSize() |
77 |
| - ) |
78 |
| - } |
79 |
| -} |
80 |
| - |
81 | 22 | from InterestingBinaryOverflowingExpr e
|
82 | 23 | where
|
83 | 24 | not isExcluded(e, IntegerConversionPackage::integerExpressionLeadToDataLossQuery()) and
|
|
0 commit comments