-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathMissingNegativityTest.ql
More file actions
67 lines (62 loc) · 2.14 KB
/
MissingNegativityTest.ql
File metadata and controls
67 lines (62 loc) · 2.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/**
* @name Unchecked return value used as offset
* @description Using a return value as a pointer offset without checking that the value is positive
* may lead to buffer overruns.
* @kind problem
* @id cpp/missing-negativity-test
* @problem.severity warning
* @tags reliability
* security
* external/cwe/cwe-823
*/
import cpp
import Negativity
class IntegralReturnValue extends FunctionCall
{
IntegralReturnValue() {
this.getType().getUnderlyingType() instanceof IntegralType
}
predicate isChecked() {
exists(ControlFlowNode def, ControlFlowNode test, Variable v |
exprDefinition(v, def, this) and
definitionReaches(def, test) and
errorSuccessor(v, test.getASuccessor()))
}
}
class FunctionWithNegativeReturn extends Function
{
FunctionWithNegativeReturn() {
this.getType().getUnderlyingType() instanceof IntegralType and
( exists(ReturnStmt ret |
ret.getExpr().getValue().toInt() < 0 and
ret.getEnclosingFunction() = this)
or
count(IntegralReturnValue val | val.getTarget() = this and val.isChecked()) * 100 /
count(IntegralReturnValue val | val.getTarget() = this) >= 80)
}
}
predicate dangerousUse(IntegralReturnValue val, Expr use)
{
exists(ArrayExpr ae | ae.getArrayOffset() = val and use = val)
or
exists(LocalScopeVariable v, ControlFlowNode def, ArrayExpr ae |
exprDefinition(v, def, val) and
use = ae.getArrayOffset() and
not boundsChecked(v, use) and
definitionUsePair(v, def, use))
or
(use.getParent().(AddExpr).getAnOperand() = val and
val = use and
use.getType().getUnderlyingType() instanceof PointerType)
or
exists(LocalScopeVariable v, ControlFlowNode def, AddExpr add |
exprDefinition(v, def, val) and
definitionUsePair(v, def, use) and
add.getAnOperand() = use and
not boundsChecked(v, use) and
add.getType().getUnderlyingType() instanceof PointerType)
}
from FunctionWithNegativeReturn f, IntegralReturnValue val, Expr dangerous
where val.getTarget() = f
and dangerousUse(val, dangerous)
select dangerous, "Dangerous use of possibly negative value (return value of '" + f.getName() + "')."