Skip to content

Commit cafd320

Browse files
committed
C++: Add set/map constructor models.
1 parent 6520f9d commit cafd320

File tree

7 files changed

+71
-7
lines changed

7 files changed

+71
-7
lines changed

cpp/ql/src/semmle/code/cpp/models/implementations/StdMap.qll

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,33 @@
55
import semmle.code.cpp.models.interfaces.Taint
66
import semmle.code.cpp.models.implementations.Iterator
77

8+
/**
9+
* Additional model for map constructors using iterator inputs.
10+
*/
11+
class StdMapConstructor extends Constructor, TaintFunction {
12+
StdMapConstructor() {
13+
this.hasQualifiedName("std", "map", "map") or
14+
this.hasQualifiedName("std", "unordered_map", "unordered_map")
15+
}
16+
17+
/**
18+
* Gets the index of a parameter to this function that is an iterator.
19+
*/
20+
int getAnIteratorParameterIndex() {
21+
getParameter(result).getUnspecifiedType() instanceof Iterator
22+
}
23+
24+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
25+
// taint flow from any parameter of an iterator type to the qualifier
26+
input.isParameterDeref(getAnIteratorParameterIndex()) and
27+
(
28+
output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object
29+
or
30+
output.isQualifierObject()
31+
)
32+
}
33+
}
34+
835
/**
936
* The standard map `insert` and `insert_or_assign` functions.
1037
*/

cpp/ql/src/semmle/code/cpp/models/implementations/StdSet.qll

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,38 @@
55
import semmle.code.cpp.models.interfaces.Taint
66
import semmle.code.cpp.models.implementations.Iterator
77

8+
/**
9+
* Additional model for set constructors using iterator inputs.
10+
*/
11+
class StdSetConstructor extends Constructor, TaintFunction {
12+
StdSetConstructor() {
13+
this.hasQualifiedName("std", "set", "set") or
14+
this.hasQualifiedName("std", "unordered_set", "unordered_set")
15+
}
16+
17+
/**
18+
* Gets the index of a parameter to this function that is an iterator.
19+
*/
20+
int getAnIteratorParameterIndex() {
21+
getParameter(result).getUnspecifiedType() instanceof Iterator
22+
}
23+
24+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
25+
// taint flow from any parameter of an iterator type to the qualifier
26+
input.isParameterDeref(getAnIteratorParameterIndex()) and
27+
(
28+
output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object
29+
or
30+
output.isQualifierObject()
31+
)
32+
}
33+
}
34+
835
/**
936
* The standard set `insert` and `insert_or_assign` functions.
1037
*/
1138
class StdSetInsert extends TaintFunction {
12-
StdSetInsert() {
13-
this.hasQualifiedName("std", ["set", "unordered_set"], "insert")
14-
}
39+
StdSetInsert() { this.hasQualifiedName("std", ["set", "unordered_set"], "insert") }
1540

1641
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
1742
// flow from last parameter to qualifier and return value

cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2095,11 +2095,13 @@
20952095
| set.cpp:41:22:41:42 | call to set | set.cpp:46:7:46:8 | s9 | |
20962096
| set.cpp:41:22:41:42 | call to set | set.cpp:50:7:50:8 | s9 | |
20972097
| set.cpp:41:22:41:42 | call to set | set.cpp:126:1:126:1 | s9 | |
2098+
| set.cpp:41:25:41:29 | call to begin | set.cpp:41:22:41:42 | call to set | TAINT |
20982099
| set.cpp:41:34:41:35 | ref arg s2 | set.cpp:43:8:43:9 | s2 | |
20992100
| set.cpp:41:34:41:35 | ref arg s2 | set.cpp:59:12:59:13 | s2 | |
21002101
| set.cpp:41:34:41:35 | ref arg s2 | set.cpp:59:30:59:31 | s2 | |
21012102
| set.cpp:41:34:41:35 | ref arg s2 | set.cpp:126:1:126:1 | s2 | |
21022103
| set.cpp:41:34:41:35 | s2 | set.cpp:41:37:41:39 | call to end | TAINT |
2104+
| set.cpp:41:37:41:39 | call to end | set.cpp:41:22:41:42 | call to set | TAINT |
21032105
| set.cpp:42:19:42:21 | call to set | set.cpp:43:2:43:4 | s10 | |
21042106
| set.cpp:42:19:42:21 | call to set | set.cpp:47:7:47:9 | s10 | |
21052107
| set.cpp:42:19:42:21 | call to set | set.cpp:51:7:51:9 | s10 | |
@@ -2569,11 +2571,13 @@
25692571
| set.cpp:155:32:155:52 | call to unordered_set | set.cpp:160:7:160:8 | s9 | |
25702572
| set.cpp:155:32:155:52 | call to unordered_set | set.cpp:164:7:164:8 | s9 | |
25712573
| set.cpp:155:32:155:52 | call to unordered_set | set.cpp:238:1:238:1 | s9 | |
2574+
| set.cpp:155:35:155:39 | call to begin | set.cpp:155:32:155:52 | call to unordered_set | TAINT |
25722575
| set.cpp:155:44:155:45 | ref arg s2 | set.cpp:157:8:157:9 | s2 | |
25732576
| set.cpp:155:44:155:45 | ref arg s2 | set.cpp:173:12:173:13 | s2 | |
25742577
| set.cpp:155:44:155:45 | ref arg s2 | set.cpp:173:30:173:31 | s2 | |
25752578
| set.cpp:155:44:155:45 | ref arg s2 | set.cpp:238:1:238:1 | s2 | |
25762579
| set.cpp:155:44:155:45 | s2 | set.cpp:155:47:155:49 | call to end | TAINT |
2580+
| set.cpp:155:47:155:49 | call to end | set.cpp:155:32:155:52 | call to unordered_set | TAINT |
25772581
| set.cpp:156:29:156:31 | call to unordered_set | set.cpp:157:2:157:4 | s10 | |
25782582
| set.cpp:156:29:156:31 | call to unordered_set | set.cpp:161:7:161:9 | s10 | |
25792583
| set.cpp:156:29:156:31 | call to unordered_set | set.cpp:165:7:165:9 | s10 | |

cpp/ql/test/library-tests/dataflow/taint-tests/set.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ void test_set()
4343
s10 = s2;
4444
sink(s7); // tainted
4545
sink(s8); // tainted
46-
sink(s9); // tainted [NOT DETECTED]
46+
sink(s9); // tainted
4747
sink(s10); // tainted
4848
sink(s7.find("abc")); // tainted
4949
sink(s8.find("abc")); // tainted
50-
sink(s9.find("abc")); // tainted [NOT DETECTED]
50+
sink(s9.find("abc")); // tainted
5151
sink(s10.find("abc")); // tainted
5252

5353
// iterators
@@ -157,11 +157,11 @@ void test_unordered_set()
157157
s10 = s2;
158158
sink(s7); // tainted
159159
sink(s8); // tainted
160-
sink(s9); // tainted [NOT DETECTED]
160+
sink(s9); // tainted
161161
sink(s10); // tainted
162162
sink(s7.find("abc")); // tainted
163163
sink(s8.find("abc")); // tainted
164-
sink(s9.find("abc")); // tainted [NOT DETECTED]
164+
sink(s9.find("abc")); // tainted
165165
sink(s10.find("abc")); // tainted
166166

167167
// iterators

cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,11 @@
198198
| set.cpp:36:10:36:13 | call to find | set.cpp:20:17:20:22 | call to source |
199199
| set.cpp:44:7:44:8 | call to set | set.cpp:20:17:20:22 | call to source |
200200
| set.cpp:45:7:45:8 | call to set | set.cpp:20:17:20:22 | call to source |
201+
| set.cpp:46:7:46:8 | call to set | set.cpp:20:17:20:22 | call to source |
201202
| set.cpp:47:7:47:9 | call to set | set.cpp:20:17:20:22 | call to source |
202203
| set.cpp:48:10:48:13 | call to find | set.cpp:20:17:20:22 | call to source |
203204
| set.cpp:49:10:49:13 | call to find | set.cpp:20:17:20:22 | call to source |
205+
| set.cpp:50:10:50:13 | call to find | set.cpp:20:17:20:22 | call to source |
204206
| set.cpp:51:11:51:14 | call to find | set.cpp:20:17:20:22 | call to source |
205207
| set.cpp:61:8:61:8 | call to operator* | set.cpp:20:17:20:22 | call to source |
206208
| set.cpp:78:7:78:9 | call to set | set.cpp:76:13:76:18 | call to source |
@@ -230,9 +232,11 @@
230232
| set.cpp:150:10:150:13 | call to find | set.cpp:134:17:134:22 | call to source |
231233
| set.cpp:158:7:158:8 | call to unordered_set | set.cpp:134:17:134:22 | call to source |
232234
| set.cpp:159:7:159:8 | call to unordered_set | set.cpp:134:17:134:22 | call to source |
235+
| set.cpp:160:7:160:8 | call to unordered_set | set.cpp:134:17:134:22 | call to source |
233236
| set.cpp:161:7:161:9 | call to unordered_set | set.cpp:134:17:134:22 | call to source |
234237
| set.cpp:162:10:162:13 | call to find | set.cpp:134:17:134:22 | call to source |
235238
| set.cpp:163:10:163:13 | call to find | set.cpp:134:17:134:22 | call to source |
239+
| set.cpp:164:10:164:13 | call to find | set.cpp:134:17:134:22 | call to source |
236240
| set.cpp:165:11:165:14 | call to find | set.cpp:134:17:134:22 | call to source |
237241
| set.cpp:175:8:175:8 | call to operator* | set.cpp:134:17:134:22 | call to source |
238242
| set.cpp:190:7:190:9 | call to unordered_set | set.cpp:188:13:188:18 | call to source |

cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@
154154
| set.cpp:30:7:30:8 | set.cpp:20:17:20:22 | AST only |
155155
| set.cpp:44:7:44:8 | set.cpp:20:17:20:22 | AST only |
156156
| set.cpp:45:7:45:8 | set.cpp:20:17:20:22 | AST only |
157+
| set.cpp:46:7:46:8 | set.cpp:20:17:20:22 | AST only |
157158
| set.cpp:47:7:47:9 | set.cpp:20:17:20:22 | AST only |
158159
| set.cpp:48:10:48:13 | set.cpp:20:17:20:22 | AST only |
159160
| set.cpp:49:10:49:13 | set.cpp:20:17:20:22 | AST only |
@@ -180,6 +181,7 @@
180181
| set.cpp:144:7:144:8 | set.cpp:134:17:134:22 | AST only |
181182
| set.cpp:158:7:158:8 | set.cpp:134:17:134:22 | AST only |
182183
| set.cpp:159:7:159:8 | set.cpp:134:17:134:22 | AST only |
184+
| set.cpp:160:7:160:8 | set.cpp:134:17:134:22 | AST only |
183185
| set.cpp:161:7:161:9 | set.cpp:134:17:134:22 | AST only |
184186
| set.cpp:162:10:162:13 | set.cpp:134:17:134:22 | AST only |
185187
| set.cpp:163:10:163:13 | set.cpp:134:17:134:22 | AST only |

cpp/ql/test/library-tests/dataflow/taint-tests/test_ir.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@
138138
| set.cpp:32:10:32:13 | call to find | set.cpp:20:17:20:22 | call to source |
139139
| set.cpp:34:10:34:13 | call to find | set.cpp:22:29:22:34 | call to source |
140140
| set.cpp:36:10:36:13 | call to find | set.cpp:20:17:20:22 | call to source |
141+
| set.cpp:50:10:50:13 | call to find | set.cpp:20:17:20:22 | call to source |
141142
| set.cpp:51:11:51:14 | call to find | set.cpp:20:17:20:22 | call to source |
142143
| set.cpp:61:8:61:8 | call to operator* | set.cpp:20:17:20:22 | call to source |
143144
| set.cpp:61:8:61:11 | (reference dereference) | set.cpp:20:17:20:22 | call to source |
@@ -148,6 +149,7 @@
148149
| set.cpp:146:10:146:13 | call to find | set.cpp:134:17:134:22 | call to source |
149150
| set.cpp:148:10:148:13 | call to find | set.cpp:136:29:136:34 | call to source |
150151
| set.cpp:150:10:150:13 | call to find | set.cpp:134:17:134:22 | call to source |
152+
| set.cpp:164:10:164:13 | call to find | set.cpp:134:17:134:22 | call to source |
151153
| set.cpp:165:11:165:14 | call to find | set.cpp:134:17:134:22 | call to source |
152154
| set.cpp:175:8:175:8 | call to operator* | set.cpp:134:17:134:22 | call to source |
153155
| set.cpp:175:8:175:11 | (reference dereference) | set.cpp:134:17:134:22 | call to source |

0 commit comments

Comments
 (0)