|
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