1
1
/**
2
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
3
+ * @description Writing 'if (a+b>c) a=c-b' incorrectly implements
4
+ * 'a = min(a,c-b)' if 'a+b' overflows. This integer
5
+ * overflow is the root cause of the buffer overflow
10
6
* in the SHA-3 reference implementation (CVE-2022-37454).
11
7
* @kind problem
12
8
* @problem.severity warning
@@ -21,22 +17,26 @@ import cpp
21
17
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
22
18
import semmle.code.cpp.valuenumbering.HashCons
23
19
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
24
- import semmle.code.cpp.commons.Exclusions
20
+ import semmle.code.cpp.controlflow.Guards
25
21
26
- from IfStmt ifstmt , RelationalOperation relop , ExprStmt exprstmt , BlockStmt blockstmt , AssignExpr assignexpr , AddExpr addexpr , SubExpr subexpr
27
- where ifstmt .getCondition ( ) = relop and
28
- relop .getAnOperand ( ) = addexpr and
22
+ from
23
+ GuardCondition guard , Expr expr , ExprStmt exprstmt , BasicBlock block , AssignExpr assignexpr ,
24
+ AddExpr addexpr , SubExpr subexpr
25
+ where
26
+ ( guard .ensuresLt ( expr , addexpr , 0 , block , _) or guard .ensuresLt ( addexpr , expr , 0 , block , _) ) and
29
27
addexpr .getUnspecifiedType ( ) instanceof IntegralType and
30
- not isFromMacroDefinition ( relop ) and
31
28
exprMightOverflowPositively ( addexpr ) and
32
- ( ifstmt .getThen ( ) = exprstmt or
33
- ( ifstmt .getThen ( ) = blockstmt and
34
- blockstmt .getAStmt ( ) = exprstmt ) ) and
29
+ block .getANode ( ) = exprstmt and
35
30
exprstmt .getExpr ( ) = assignexpr and
36
31
assignexpr .getRValue ( ) = subexpr and
37
- ( ( hashCons ( addexpr .getLeftOperand ( ) ) = hashCons ( assignexpr .getLValue ( ) ) and
38
- globalValueNumber ( addexpr .getRightOperand ( ) ) = globalValueNumber ( subexpr .getRightOperand ( ) ) ) or
39
- ( hashCons ( addexpr .getRightOperand ( ) ) = hashCons ( assignexpr .getLValue ( ) ) and
40
- globalValueNumber ( addexpr .getLeftOperand ( ) ) = globalValueNumber ( subexpr .getRightOperand ( ) ) ) ) and
41
- globalValueNumber ( relop .getAnOperand ( ) ) = globalValueNumber ( subexpr .getLeftOperand ( ) )
42
- select ifstmt , "\"if (a+b>c) a=c-b\" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as \"if (a>c-b) a=c-b\" which avoids the overflow." , addexpr , "addition"
32
+ (
33
+ hashCons ( addexpr .getLeftOperand ( ) ) = hashCons ( assignexpr .getLValue ( ) ) and
34
+ globalValueNumber ( addexpr .getRightOperand ( ) ) = globalValueNumber ( subexpr .getRightOperand ( ) )
35
+ or
36
+ hashCons ( addexpr .getRightOperand ( ) ) = hashCons ( assignexpr .getLValue ( ) ) and
37
+ globalValueNumber ( addexpr .getLeftOperand ( ) ) = globalValueNumber ( subexpr .getRightOperand ( ) )
38
+ ) and
39
+ globalValueNumber ( expr ) = globalValueNumber ( subexpr .getLeftOperand ( ) )
40
+ select guard ,
41
+ "\"if (a+b>c) a=c-b\" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as \"if (a>c-b) a=c-b\" which avoids the overflow." ,
42
+ addexpr , "addition"
0 commit comments