|
1 | 1 | /**
|
2 |
| - * @name Integer addition may overflow inside condition |
3 |
| - * @description Detects "c-b" when the condition "a+b>c" has been imposed, |
4 |
| - * which is not the same as the condition "a>b-c" if "a+b" |
5 |
| - * overflows. Rewriting improves readability and optimizability |
6 |
| - * (CSE elimination). Also detects "b+a>c" (swapped terms in |
7 |
| - * addition), "c<a+b" (swapped operands), and ">=", "<", |
8 |
| - * "<=" instead of ">" (all operators). This integer overflow |
9 |
| - * is the root cause of the buffer overflow in the SHA-3 |
10 |
| - * reference implementation (CVE-2022-37454). |
| 2 | + * @name Integer addition may overflow inside if statement |
| 3 | + * @description Detects "if (a+b>c) a=c-b", which incorrectly implements |
| 4 | + * a = min(a,c-b) if a+b overflows. Should be replaced by |
| 5 | + * "if (a>c-b) a=c-b". Also detects "if (b+a>c) a=c-b" |
| 6 | + * (swapped terms in addition), if (a+b>c) { a=c-b }" |
| 7 | + * (assignment inside block), "c<a+b" (swapped operands) and |
| 8 | + * ">=", "<", "<=" instead of ">" (all operators). This |
| 9 | + * integer overflow is the root cause of the buffer overflow |
| 10 | + * in the SHA-3 reference implementation (CVE-2022-37454). |
11 | 11 | * @kind problem
|
12 | 12 | * @problem.severity warning
|
13 | 13 | * @id cpp/if-statement-addition-overflow
|
|
18 | 18 | */
|
19 | 19 |
|
20 | 20 | import cpp
|
21 |
| -import semmle.code.cpp.controlflow.Guards |
22 | 21 | import semmle.code.cpp.valuenumbering.GlobalValueNumbering
|
| 22 | +import semmle.code.cpp.valuenumbering.HashCons |
23 | 23 | import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
|
24 | 24 | import semmle.code.cpp.commons.Exclusions
|
25 | 25 |
|
26 |
| -from GuardCondition guard, BasicBlock block, RelationalOperation relop, AddExpr addexpr, SubExpr subexpr |
27 |
| -where guard.controls(block, _) and |
28 |
| - guard.getAChild*() = relop and |
29 |
| - pragma[only_bind_into](block) = subexpr.getBasicBlock() and |
| 26 | +from IfStmt ifstmt, RelationalOperation relop, ExprStmt exprstmt, BlockStmt blockstmt, AssignExpr assignexpr, AddExpr addexpr, SubExpr subexpr |
| 27 | +where ifstmt.getCondition() = relop and |
30 | 28 | relop.getAnOperand() = addexpr and
|
31 | 29 | addexpr.getUnspecifiedType() instanceof IntegralType and
|
| 30 | + subexpr.getUnspecifiedType() instanceof IntegralType and |
32 | 31 | not isFromMacroDefinition(relop) and
|
33 | 32 | exprMightOverflowPositively(addexpr) and
|
34 |
| - globalValueNumber(addexpr.getAnOperand()) = globalValueNumber(subexpr.getRightOperand()) and |
35 |
| - globalValueNumber(relop.getAnOperand()) = globalValueNumber(subexpr.getLeftOperand()) |
36 |
| -select guard, "Integer addition may overflow inside condition." |
| 33 | + (ifstmt.getThen() = exprstmt or |
| 34 | + (ifstmt.getThen() = blockstmt and |
| 35 | + blockstmt.getAStmt() = exprstmt)) and |
| 36 | + exprstmt.getExpr() = assignexpr and |
| 37 | + assignexpr.getRValue() = subexpr and |
| 38 | + ((hashCons(addexpr.getLeftOperand()) = hashCons(assignexpr.getLValue()) and |
| 39 | + globalValueNumber(addexpr.getRightOperand()) = globalValueNumber(subexpr.getRightOperand())) or |
| 40 | + (hashCons(addexpr.getRightOperand()) = hashCons(assignexpr.getLValue()) and |
| 41 | + globalValueNumber(addexpr.getLeftOperand()) = globalValueNumber(subexpr.getRightOperand()))) and |
| 42 | + globalValueNumber(relop.getAnOperand()) = globalValueNumber(subexpr.getLeftOperand()) and |
| 43 | + not globalValueNumber(addexpr.getAnOperand()) = globalValueNumber(relop.getAnOperand()) |
| 44 | +select ifstmt, "Integer addition may overflow inside if statement." |
0 commit comments