Skip to content

Commit e8bba78

Browse files
committed
C++: Convert 'cpp/uncontrolled-arithmetic' to use a 'TaintTracking::Configuration'.
1 parent c0ffd90 commit e8bba78

File tree

3 files changed

+44
-91
lines changed

3 files changed

+44
-91
lines changed

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

Lines changed: 30 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@
1515
import cpp
1616
import semmle.code.cpp.security.Overflow
1717
import semmle.code.cpp.security.Security
18-
import semmle.code.cpp.security.TaintTracking
19-
import TaintedWithPath
18+
import semmle.code.cpp.security.FlowSources
19+
import semmle.code.cpp.ir.dataflow.TaintTracking
20+
import DataFlow::PathGraph
2021
import Bounded
2122

2223
/**
@@ -71,36 +72,6 @@ private class RandS extends RandomFunction {
7172
override FunctionOutput getFunctionOutput() { result.isParameterDeref(0) }
7273
}
7374

74-
predicate isUnboundedRandCall(FunctionCall fc) {
75-
exists(Function func | func = fc.getTarget() |
76-
func.hasGlobalOrStdOrBslName("rand") and
77-
not bounded(fc) and
78-
func.getNumberOfParameters() = 0
79-
)
80-
}
81-
82-
predicate isUnboundedRandCallOrParent(Expr e) {
83-
isUnboundedRandCall(e)
84-
or
85-
isUnboundedRandCallOrParent(e.getAChild())
86-
}
87-
88-
predicate isUnboundedRandValue(Expr e) {
89-
isUnboundedRandCall(e)
90-
or
91-
exists(MacroInvocation mi |
92-
e = mi.getExpr() and
93-
isUnboundedRandCallOrParent(e)
94-
)
95-
}
96-
97-
class SecurityOptionsArith extends SecurityOptions {
98-
override predicate isUserInput(Expr expr, string cause) {
99-
isUnboundedRandValue(expr) and
100-
cause = "rand"
101-
}
102-
}
103-
10475
predicate missingGuard(VariableAccess va, string effect) {
10576
exists(Operation op | op.getAnOperand() = va |
10677
missingGuardAgainstUnderflow(op, va) and effect = "underflow"
@@ -109,16 +80,35 @@ predicate missingGuard(VariableAccess va, string effect) {
10980
)
11081
}
11182

112-
class Configuration extends TaintTrackingConfiguration {
113-
override predicate isSink(Element e) { missingGuard(e, _) }
83+
class UncontrolledArithConfiguration extends TaintTracking::Configuration {
84+
UncontrolledArithConfiguration() { this = "UncontrolledArithConfiguration" }
11485

115-
override predicate isBarrier(Expr e) { super.isBarrier(e) or bounded(e) }
86+
override predicate isSource(DataFlow::Node source) {
87+
exists(RandomFunction rand, Call call | call.getTarget() = rand |
88+
rand.getFunctionOutput().isReturnValue() and
89+
source.asExpr() = call
90+
or
91+
exists(int n |
92+
source.asDefiningArgument() = call.getArgument(n) and
93+
rand.getFunctionOutput().isParameterDeref(n)
94+
)
95+
)
96+
}
97+
98+
override predicate isSink(DataFlow::Node sink) { missingGuard(sink.asExpr(), _) }
99+
100+
override predicate isSanitizer(DataFlow::Node barrier) { bounded(barrier.asExpr()) }
116101
}
117102

118-
from Expr origin, VariableAccess va, string effect, PathNode sourceNode, PathNode sinkNode
103+
Expr getExpr(DataFlow::Node node) { result = [node.asExpr(), node.asDefiningArgument()] }
104+
105+
from
106+
UncontrolledArithConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink,
107+
VariableAccess va, string effect
119108
where
120-
taintedWithPath(origin, va, sourceNode, sinkNode) and
109+
config.hasFlowPath(source, sink) and
110+
sink.getNode().asExpr() = va and
121111
missingGuard(va, effect)
122-
select va, sourceNode, sinkNode,
123-
"$@ flows to here and is used in arithmetic, potentially causing an " + effect + ".", origin,
124-
"Uncontrolled value"
112+
select sink.getNode(), source, sink,
113+
"$@ flows to here and is used in arithmetic, potentially causing an " + effect + ".",
114+
getExpr(source.getNode()), "Uncontrolled value"

cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/uncontrolled/ArithmeticUncontrolled.expected

Lines changed: 13 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,60 @@
11
edges
22
| test.c:18:13:18:16 | call to rand | test.c:21:17:21:17 | r |
3-
| test.c:18:13:18:16 | call to rand | test.c:21:17:21:17 | r |
4-
| test.c:18:13:18:16 | call to rand | test.c:21:17:21:17 | r |
5-
| test.c:18:13:18:16 | call to rand | test.c:21:17:21:17 | r |
6-
| test.c:34:13:34:18 | call to rand | test.c:35:5:35:5 | r |
7-
| test.c:34:13:34:18 | call to rand | test.c:35:5:35:5 | r |
8-
| test.c:34:13:34:18 | call to rand | test.c:35:5:35:5 | r |
93
| test.c:34:13:34:18 | call to rand | test.c:35:5:35:5 | r |
104
| test.c:44:13:44:16 | call to rand | test.c:45:5:45:5 | r |
11-
| test.c:44:13:44:16 | call to rand | test.c:45:5:45:5 | r |
12-
| test.c:44:13:44:16 | call to rand | test.c:45:5:45:5 | r |
13-
| test.c:44:13:44:16 | call to rand | test.c:45:5:45:5 | r |
14-
| test.c:75:13:75:19 | ... ^ ... | test.c:77:9:77:9 | r |
15-
| test.c:75:13:75:19 | ... ^ ... | test.c:77:9:77:9 | r |
16-
| test.c:75:13:75:19 | ... ^ ... | test.c:77:9:77:9 | r |
17-
| test.c:75:13:75:19 | ... ^ ... | test.c:77:9:77:9 | r |
18-
| test.c:99:14:99:19 | call to rand | test.c:100:5:100:5 | r |
19-
| test.c:99:14:99:19 | call to rand | test.c:100:5:100:5 | r |
20-
| test.c:99:14:99:19 | call to rand | test.c:100:5:100:5 | r |
5+
| test.c:75:13:75:19 | call to rand | test.c:77:9:77:9 | r |
6+
| test.c:75:13:75:19 | call to rand | test.c:77:9:77:9 | r |
7+
| test.c:81:14:81:17 | call to rand | test.c:83:9:83:9 | r |
8+
| test.c:81:23:81:26 | call to rand | test.c:83:9:83:9 | r |
219
| test.c:99:14:99:19 | call to rand | test.c:100:5:100:5 | r |
2210
| test.cpp:8:9:8:12 | Store | test.cpp:24:11:24:18 | call to get_rand |
2311
| test.cpp:8:9:8:12 | call to rand | test.cpp:8:9:8:12 | Store |
24-
| test.cpp:8:9:8:12 | call to rand | test.cpp:8:9:8:12 | Store |
2512
| test.cpp:13:2:13:15 | Chi [array content] | test.cpp:30:13:30:14 | get_rand2 output argument [array content] |
2613
| test.cpp:13:10:13:13 | call to rand | test.cpp:13:2:13:15 | Chi [array content] |
27-
| test.cpp:13:10:13:13 | call to rand | test.cpp:13:2:13:15 | Chi [array content] |
2814
| test.cpp:18:2:18:14 | Chi [array content] | test.cpp:36:13:36:13 | get_rand3 output argument [array content] |
2915
| test.cpp:18:9:18:12 | call to rand | test.cpp:18:2:18:14 | Chi [array content] |
30-
| test.cpp:18:9:18:12 | call to rand | test.cpp:18:2:18:14 | Chi [array content] |
31-
| test.cpp:24:11:24:18 | call to get_rand | test.cpp:25:7:25:7 | r |
3216
| test.cpp:24:11:24:18 | call to get_rand | test.cpp:25:7:25:7 | r |
3317
| test.cpp:30:13:30:14 | Chi | test.cpp:31:7:31:7 | r |
34-
| test.cpp:30:13:30:14 | Chi | test.cpp:31:7:31:7 | r |
3518
| test.cpp:30:13:30:14 | get_rand2 output argument [array content] | test.cpp:30:13:30:14 | Chi |
3619
| test.cpp:36:13:36:13 | Chi | test.cpp:37:7:37:7 | r |
37-
| test.cpp:36:13:36:13 | Chi | test.cpp:37:7:37:7 | r |
3820
| test.cpp:36:13:36:13 | get_rand3 output argument [array content] | test.cpp:36:13:36:13 | Chi |
3921
nodes
4022
| test.c:18:13:18:16 | call to rand | semmle.label | call to rand |
41-
| test.c:18:13:18:16 | call to rand | semmle.label | call to rand |
42-
| test.c:21:17:21:17 | r | semmle.label | r |
43-
| test.c:21:17:21:17 | r | semmle.label | r |
4423
| test.c:21:17:21:17 | r | semmle.label | r |
4524
| test.c:34:13:34:18 | call to rand | semmle.label | call to rand |
46-
| test.c:34:13:34:18 | call to rand | semmle.label | call to rand |
47-
| test.c:35:5:35:5 | r | semmle.label | r |
48-
| test.c:35:5:35:5 | r | semmle.label | r |
4925
| test.c:35:5:35:5 | r | semmle.label | r |
5026
| test.c:44:13:44:16 | call to rand | semmle.label | call to rand |
51-
| test.c:44:13:44:16 | call to rand | semmle.label | call to rand |
52-
| test.c:45:5:45:5 | r | semmle.label | r |
5327
| test.c:45:5:45:5 | r | semmle.label | r |
54-
| test.c:45:5:45:5 | r | semmle.label | r |
55-
| test.c:75:13:75:19 | ... ^ ... | semmle.label | ... ^ ... |
56-
| test.c:75:13:75:19 | ... ^ ... | semmle.label | ... ^ ... |
57-
| test.c:77:9:77:9 | r | semmle.label | r |
58-
| test.c:77:9:77:9 | r | semmle.label | r |
28+
| test.c:75:13:75:19 | call to rand | semmle.label | call to rand |
29+
| test.c:75:13:75:19 | call to rand | semmle.label | call to rand |
5930
| test.c:77:9:77:9 | r | semmle.label | r |
31+
| test.c:81:14:81:17 | call to rand | semmle.label | call to rand |
32+
| test.c:81:23:81:26 | call to rand | semmle.label | call to rand |
33+
| test.c:83:9:83:9 | r | semmle.label | r |
6034
| test.c:99:14:99:19 | call to rand | semmle.label | call to rand |
61-
| test.c:99:14:99:19 | call to rand | semmle.label | call to rand |
62-
| test.c:100:5:100:5 | r | semmle.label | r |
63-
| test.c:100:5:100:5 | r | semmle.label | r |
6435
| test.c:100:5:100:5 | r | semmle.label | r |
6536
| test.cpp:8:9:8:12 | Store | semmle.label | Store |
6637
| test.cpp:8:9:8:12 | call to rand | semmle.label | call to rand |
67-
| test.cpp:8:9:8:12 | call to rand | semmle.label | call to rand |
6838
| test.cpp:13:2:13:15 | Chi [array content] | semmle.label | Chi [array content] |
69-
| test.cpp:13:2:13:15 | ChiPartial | semmle.label | ChiPartial |
70-
| test.cpp:13:10:13:13 | call to rand | semmle.label | call to rand |
7139
| test.cpp:13:10:13:13 | call to rand | semmle.label | call to rand |
7240
| test.cpp:18:2:18:14 | Chi [array content] | semmle.label | Chi [array content] |
73-
| test.cpp:18:2:18:14 | ChiPartial | semmle.label | ChiPartial |
74-
| test.cpp:18:9:18:12 | call to rand | semmle.label | call to rand |
7541
| test.cpp:18:9:18:12 | call to rand | semmle.label | call to rand |
7642
| test.cpp:24:11:24:18 | call to get_rand | semmle.label | call to get_rand |
7743
| test.cpp:25:7:25:7 | r | semmle.label | r |
78-
| test.cpp:25:7:25:7 | r | semmle.label | r |
79-
| test.cpp:25:7:25:7 | r | semmle.label | r |
8044
| test.cpp:30:13:30:14 | Chi | semmle.label | Chi |
8145
| test.cpp:30:13:30:14 | get_rand2 output argument [array content] | semmle.label | get_rand2 output argument [array content] |
8246
| test.cpp:31:7:31:7 | r | semmle.label | r |
83-
| test.cpp:31:7:31:7 | r | semmle.label | r |
84-
| test.cpp:31:7:31:7 | r | semmle.label | r |
8547
| test.cpp:36:13:36:13 | Chi | semmle.label | Chi |
8648
| test.cpp:36:13:36:13 | get_rand3 output argument [array content] | semmle.label | get_rand3 output argument [array content] |
8749
| test.cpp:37:7:37:7 | r | semmle.label | r |
88-
| test.cpp:37:7:37:7 | r | semmle.label | r |
89-
| test.cpp:37:7:37:7 | r | semmle.label | r |
9050
#select
9151
| test.c:21:17:21:17 | r | test.c:18:13:18:16 | call to rand | test.c:21:17:21:17 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:18:13:18:16 | call to rand | Uncontrolled value |
9252
| test.c:35:5:35:5 | r | test.c:34:13:34:18 | call to rand | test.c:35:5:35:5 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:34:13:34:18 | call to rand | Uncontrolled value |
9353
| test.c:45:5:45:5 | r | test.c:44:13:44:16 | call to rand | test.c:45:5:45:5 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:44:13:44:16 | call to rand | Uncontrolled value |
94-
| test.c:77:9:77:9 | r | test.c:75:13:75:19 | ... ^ ... | test.c:77:9:77:9 | r | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test.c:75:13:75:19 | ... ^ ... | Uncontrolled value |
54+
| test.c:77:9:77:9 | r | test.c:75:13:75:19 | call to rand | test.c:77:9:77:9 | r | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test.c:75:13:75:19 | call to rand | Uncontrolled value |
55+
| test.c:77:9:77:9 | r | test.c:75:13:75:19 | call to rand | test.c:77:9:77:9 | r | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test.c:75:13:75:19 | call to rand | Uncontrolled value |
56+
| test.c:83:9:83:9 | r | test.c:81:14:81:17 | call to rand | test.c:83:9:83:9 | r | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test.c:81:14:81:17 | call to rand | Uncontrolled value |
57+
| test.c:83:9:83:9 | r | test.c:81:23:81:26 | call to rand | test.c:83:9:83:9 | r | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test.c:81:23:81:26 | call to rand | Uncontrolled value |
9558
| test.c:100:5:100:5 | r | test.c:99:14:99:19 | call to rand | test.c:100:5:100:5 | r | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test.c:99:14:99:19 | call to rand | Uncontrolled value |
9659
| test.cpp:25:7:25:7 | r | test.cpp:8:9:8:12 | call to rand | test.cpp:25:7:25:7 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.cpp:8:9:8:12 | call to rand | Uncontrolled value |
9760
| test.cpp:31:7:31:7 | r | test.cpp:13:10:13:13 | call to rand | test.cpp:31:7:31:7 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.cpp:13:10:13:13 | call to rand | Uncontrolled value |

cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/uncontrolled/test.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ void randomTester() {
8080
{
8181
int r = (rand() ^ rand());
8282

83-
r = r - 100; // BAD [NOT DETECTED]
83+
r = r - 100; // BAD
8484
}
8585

8686
{

0 commit comments

Comments
 (0)