Skip to content

Commit ed75172

Browse files
authored
Update IfStatementAdditionOverflow.ql
1 parent f577a04 commit ed75172

File tree

1 file changed

+25
-17
lines changed

1 file changed

+25
-17
lines changed
Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
/**
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).
1111
* @kind problem
1212
* @problem.severity warning
1313
* @id cpp/if-statement-addition-overflow
@@ -18,19 +18,27 @@
1818
*/
1919

2020
import cpp
21-
import semmle.code.cpp.controlflow.Guards
2221
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
22+
import semmle.code.cpp.valuenumbering.HashCons
2323
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
2424
import semmle.code.cpp.commons.Exclusions
2525

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
3028
relop.getAnOperand() = addexpr and
3129
addexpr.getUnspecifiedType() instanceof IntegralType and
30+
subexpr.getUnspecifiedType() instanceof IntegralType and
3231
not isFromMacroDefinition(relop) and
3332
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

Comments
 (0)