|
1 | 1 | /**
|
2 |
| - * @name Integer addition may overflow inside if statement |
3 |
| - * @description Detects "if (a+b>c) a=c-b", which is incorrect if a+b overflows. |
4 |
| - * Should be replaced by "if (a>c-b) a=c-b", which correctly |
5 |
| - * implements a = min(a,c-b)". This integer overflow is the root |
6 |
| - * cause of the buffer overflow in the SHA-3 reference implementation |
7 |
| - * (CVE-2022-37454). |
| 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). |
8 | 11 | * @kind problem
|
9 | 12 | * @problem.severity warning
|
10 | 13 | * @id cpp/if-statement-addition-overflow
|
|
15 | 18 | */
|
16 | 19 |
|
17 | 20 | import cpp
|
| 21 | +import semmle.code.cpp.controlflow.Guards |
| 22 | +import semmle.code.cpp.valuenumbering.GlobalValueNumbering |
| 23 | +import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis |
| 24 | +import semmle.code.cpp.commons.Exclusions |
18 | 25 |
|
19 |
| -from IfStmt ifstmt, GTExpr gtexpr, ExprStmt exprstmt, AssignExpr assignexpr, AddExpr addexpr, SubExpr subexpr |
20 |
| -where ifstmt.getCondition() = gtexpr and |
21 |
| - gtexpr.getLeftOperand() = addexpr and |
22 |
| - ifstmt.getThen() = exprstmt and |
23 |
| - exprstmt.getExpr() = assignexpr and |
24 |
| - assignexpr.getRValue() = subexpr and |
25 |
| - addexpr.getLeftOperand().toString() = assignexpr.getLValue().toString() and |
26 |
| - addexpr.getRightOperand().toString() = subexpr.getRightOperand().toString() and |
27 |
| - gtexpr.getRightOperand().toString() = subexpr.getLeftOperand().toString() |
28 |
| -select ifstmt, "Integer addition may overflow inside if statement." |
| 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 |
| 30 | + relop.getAnOperand() = addexpr and |
| 31 | + addexpr.getUnspecifiedType() instanceof IntegralType and |
| 32 | + not isFromMacroDefinition(relop) and |
| 33 | + 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." |
0 commit comments