Skip to content

Commit 418a167

Browse files
authored
Merge pull request #105 from geoffw0/samate-crement
CPP: Support crement operations in CWE-190
2 parents 1d202dd + 0d63739 commit 418a167

File tree

5 files changed

+34
-15
lines changed

5 files changed

+34
-15
lines changed

change-notes/1.18/analysis-cpp.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,11 @@
2626
| [Variable used in its own initializer] | Fewer false positive results | Results where a macro is used to indicate deliberate uninitialization are now excluded |
2727
| [Assignment where comparison was intended] | Fewer false positive results | Results are no longer reported if the variable is not yet defined. |
2828
| [Comparison where assignment was intended] | More correct results | "This query now includes results where an overloaded `operator==` is used in the wrong context. |
29-
29+
| [User-controlled data in arithmetic expression] | More correct results | Increment / decrement / addition assignment / subtraction assignment operations are now understood as arithmetic operations in this query. |
30+
| [Uncontrolled data in arithmetic expression] | More correct results | Increment / decrement / addition assignment / subtraction assignment operations are now understood as arithmetic operations in this query. |
31+
| [Use of extreme values in arithmetic expression] | More correct results | Increment / decrement / addition assignment / subtraction assignment operations are now understood as arithmetic operations in this query. |
32+
| [Use of extreme values in arithmetic expression] | Fewer false positives | The query now considers whether a particular expression might cause an overflow of minimum or maximum values only. |
33+
3034
## Changes to QL libraries
3135

3236
* *Series of bullet points*

cpp/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ predicate taintedVarAccess(Expr origin, VariableAccess va) {
2121
tainted(origin, va)
2222
}
2323

24-
from Expr origin, BinaryArithmeticOperation op, VariableAccess va, string effect
24+
from Expr origin, Operation op, VariableAccess va, string effect
2525
where taintedVarAccess(origin, va)
2626
and op.getAnOperand() = va
2727
and

cpp/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ predicate guardedByAssignDiv(Expr origin) {
4646
tainted(origin, va) and div.getLValue() = va)
4747
}
4848

49-
from Expr origin, BinaryArithmeticOperation op, VariableAccess va, string effect
49+
from Expr origin, Operation op, VariableAccess va, string effect
5050
where taintedVarAccess(origin, va)
5151
and op.getAnOperand() = va
5252
and

cpp/ql/src/Security/CWE/CWE-190/ArithmeticWithExtremeValues.ql

+16-5
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,29 @@ class SecurityOptionsArith extends SecurityOptions {
4040
}
4141
}
4242

43-
predicate taintedVarAccess(Expr origin, VariableAccess va) {
44-
isUserInput(origin, _) and
43+
predicate taintedVarAccess(Expr origin, VariableAccess va, string cause) {
44+
isUserInput(origin, cause) and
4545
tainted(origin, va)
4646
}
4747

48-
from Expr origin, BinaryArithmeticOperation op, VariableAccess va, string effect
49-
where taintedVarAccess(origin, va)
48+
predicate causeEffectCorrespond(string cause, string effect) {
49+
(
50+
cause = "max value" and
51+
effect = "overflow"
52+
) or (
53+
cause = "min value" and
54+
effect = "underflow"
55+
)
56+
}
57+
58+
from Expr origin, Operation op, VariableAccess va, string cause, string effect
59+
where taintedVarAccess(origin, va, cause)
5060
and op.getAnOperand() = va
5161
and
5262
(
5363
(missingGuardAgainstUnderflow(op, va) and effect = "underflow") or
5464
(missingGuardAgainstOverflow(op, va) and effect = "overflow")
55-
)
65+
) and
66+
causeEffectCorrespond(cause, effect)
5667
select va, "$@ flows to here and is used in arithmetic, potentially causing an " + effect + ".",
5768
origin, "Extreme value"

cpp/ql/src/semmle/code/cpp/security/Overflow.qll

+11-7
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import semmle.code.cpp.controlflow.Dominance
44
/* Guarding */
55

66
/** is the size of this use guarded using 'abs'? */
7-
predicate guardedAbs(BinaryArithmeticOperation e, Expr use) {
7+
predicate guardedAbs(Operation e, Expr use) {
88
exists(FunctionCall fc |
99
fc.getTarget().getName() = "abs" |
1010
fc.getArgument(0).getAChild*() = use
@@ -13,7 +13,7 @@ predicate guardedAbs(BinaryArithmeticOperation e, Expr use) {
1313
}
1414

1515
/** is the size of this use guarded to be less than something? */
16-
predicate guardedLesser(BinaryArithmeticOperation e, Expr use) {
16+
predicate guardedLesser(Operation e, Expr use) {
1717
exists(IfStmt c, RelationalOperation guard |
1818
use = guard.getLesserOperand().getAChild*() and
1919
guard = c.getControllingExpr().getAChild*() and
@@ -33,7 +33,7 @@ predicate guardedLesser(BinaryArithmeticOperation e, Expr use) {
3333
}
3434

3535
/** is the size of this use guarded to be greater than something? */
36-
predicate guardedGreater(BinaryArithmeticOperation e, Expr use) {
36+
predicate guardedGreater(Operation e, Expr use) {
3737
exists(IfStmt c, RelationalOperation guard |
3838
use = guard.getGreaterOperand().getAChild*() and
3939
guard = c.getControllingExpr().getAChild*() and
@@ -58,24 +58,28 @@ VariableAccess varUse(LocalScopeVariable v) {
5858
}
5959

6060
/** is e not guarded against overflow by use? */
61-
predicate missingGuardAgainstOverflow(BinaryArithmeticOperation e, VariableAccess use) {
61+
predicate missingGuardAgainstOverflow(Operation e, VariableAccess use) {
6262
use = e.getAnOperand() and
6363
exists(LocalScopeVariable v | use.getTarget() = v |
6464
// overflow possible if large
6565
(e instanceof AddExpr and not guardedLesser(e, varUse(v))) or
66+
(e instanceof AssignAddExpr and not guardedLesser(e, varUse(v))) or
67+
(e instanceof IncrementOperation and not guardedLesser(e, varUse(v)) and v.getType().getUnspecifiedType() instanceof IntegralType) or
6668
// overflow possible if large or small
6769
(e instanceof MulExpr and
6870
not (guardedLesser(e, varUse(v)) and guardedGreater(e, varUse(v))))
6971
)
7072
}
7173

7274
/** is e not guarded against underflow by use? */
73-
predicate missingGuardAgainstUnderflow(BinaryArithmeticOperation e, VariableAccess use) {
75+
predicate missingGuardAgainstUnderflow(Operation e, VariableAccess use) {
7476
use = e.getAnOperand() and
7577
exists(LocalScopeVariable v | use.getTarget() = v |
7678
// underflow possible if use is left operand and small
77-
(e instanceof SubExpr and
78-
(use = e.getLeftOperand() and not guardedGreater(e, varUse(v)))) or
79+
(use = e.(SubExpr).getLeftOperand() and not guardedGreater(e, varUse(v))) or
80+
(use = e.(AssignSubExpr).getLValue() and not guardedGreater(e, varUse(v))) or
81+
// underflow possible if small
82+
(e instanceof DecrementOperation and not guardedGreater(e, varUse(v)) and v.getType().getUnspecifiedType() instanceof IntegralType) or
7983
// underflow possible if large or small
8084
(e instanceof MulExpr and
8185
not (guardedLesser(e, varUse(v)) and guardedGreater(e, varUse(v))))

0 commit comments

Comments
 (0)