Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b73ff8d

Browse files
committed
C++: Flow through operator<<.
1 parent 6ef67af commit b73ff8d

5 files changed

Lines changed: 116 additions & 10 deletions

File tree

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

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,3 +287,56 @@ class StdStringAt extends TaintFunction {
287287
output.isQualifierObject()
288288
}
289289
}
290+
291+
/**
292+
* The `std::basic_ostream` template class.
293+
*/
294+
class StdBasicOStream extends TemplateClass {
295+
StdBasicOStream() { this.hasQualifiedName("std", "basic_ostream") }
296+
}
297+
298+
/**
299+
* The `std::ostream` function `operator<<` (defined as a member function).
300+
*/
301+
class StdOStreamOut extends TaintFunction {
302+
StdOStreamOut() { this.hasQualifiedName("std", "basic_ostream", "operator<<") }
303+
304+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
305+
// flow from parameter to qualifier
306+
input.isParameter(0) and
307+
output.isQualifierObject()
308+
or
309+
// flow from parameter to return value
310+
input.isParameter(0) and
311+
output.isReturnValueDeref()
312+
or
313+
// flow from qualifier to return value
314+
input.isQualifierObject() and
315+
output.isReturnValueDeref()
316+
}
317+
}
318+
319+
/**
320+
* The `std::ostream` function `operator<<` (defined as a non-member function).
321+
*/
322+
class StdOStreamOutNonMember extends TaintFunction {
323+
StdOStreamOutNonMember() {
324+
this.hasQualifiedName("std", "operator<<") and
325+
this.getUnspecifiedType().(ReferenceType).getBaseType() =
326+
any(StdBasicOStream s).getAnInstantiation()
327+
}
328+
329+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
330+
// flow from second parameter to first parameter
331+
input.isParameter(1) and
332+
output.isParameterDeref(0)
333+
or
334+
// flow from second parameter to return value
335+
input.isParameter(1) and
336+
output.isReturnValueDeref()
337+
or
338+
// flow from first parameter to return value
339+
input.isParameter(0) and
340+
output.isReturnValueDeref()
341+
}
342+
}

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1394,14 +1394,35 @@
13941394
| stringstream.cpp:29:16:29:24 | call to basic_string | stringstream.cpp:35:14:35:14 | t | |
13951395
| stringstream.cpp:31:7:31:9 | ref arg ss1 | stringstream.cpp:37:7:37:9 | ss1 | |
13961396
| stringstream.cpp:31:7:31:9 | ref arg ss1 | stringstream.cpp:42:7:42:9 | ss1 | |
1397+
| stringstream.cpp:31:7:31:9 | ss1 | stringstream.cpp:31:11:31:11 | call to operator<< | TAINT |
1398+
| stringstream.cpp:31:14:31:19 | 1234 | stringstream.cpp:31:7:31:9 | ref arg ss1 | TAINT |
1399+
| stringstream.cpp:31:14:31:19 | 1234 | stringstream.cpp:31:11:31:11 | call to operator<< | TAINT |
13971400
| stringstream.cpp:32:7:32:9 | ref arg ss2 | stringstream.cpp:38:7:38:9 | ss2 | |
13981401
| stringstream.cpp:32:7:32:9 | ref arg ss2 | stringstream.cpp:43:7:43:9 | ss2 | |
1402+
| stringstream.cpp:32:7:32:9 | ss2 | stringstream.cpp:32:11:32:11 | call to operator<< | TAINT |
1403+
| stringstream.cpp:32:14:32:19 | call to source | stringstream.cpp:32:7:32:9 | ref arg ss2 | TAINT |
1404+
| stringstream.cpp:32:14:32:19 | call to source | stringstream.cpp:32:11:32:11 | call to operator<< | TAINT |
13991405
| stringstream.cpp:33:7:33:9 | ref arg ss3 | stringstream.cpp:39:7:39:9 | ss3 | |
14001406
| stringstream.cpp:33:7:33:9 | ref arg ss3 | stringstream.cpp:44:7:44:9 | ss3 | |
1407+
| stringstream.cpp:33:7:33:9 | ss3 | stringstream.cpp:33:11:33:11 | call to operator<< | TAINT |
1408+
| stringstream.cpp:33:11:33:11 | call to operator<< | stringstream.cpp:33:20:33:20 | call to operator<< | TAINT |
1409+
| stringstream.cpp:33:14:33:18 | 123 | stringstream.cpp:33:7:33:9 | ref arg ss3 | TAINT |
1410+
| stringstream.cpp:33:14:33:18 | 123 | stringstream.cpp:33:11:33:11 | call to operator<< | TAINT |
1411+
| stringstream.cpp:33:23:33:28 | call to source | stringstream.cpp:33:11:33:11 | ref arg call to operator<< | TAINT |
1412+
| stringstream.cpp:33:23:33:28 | call to source | stringstream.cpp:33:20:33:20 | call to operator<< | TAINT |
14011413
| stringstream.cpp:34:7:34:9 | ref arg ss4 | stringstream.cpp:40:7:40:9 | ss4 | |
14021414
| stringstream.cpp:34:7:34:9 | ref arg ss4 | stringstream.cpp:45:7:45:9 | ss4 | |
1415+
| stringstream.cpp:34:7:34:9 | ss4 | stringstream.cpp:34:11:34:11 | call to operator<< | TAINT |
1416+
| stringstream.cpp:34:11:34:11 | call to operator<< | stringstream.cpp:34:23:34:23 | call to operator<< | TAINT |
1417+
| stringstream.cpp:34:14:34:19 | call to source | stringstream.cpp:34:7:34:9 | ref arg ss4 | TAINT |
1418+
| stringstream.cpp:34:14:34:19 | call to source | stringstream.cpp:34:11:34:11 | call to operator<< | TAINT |
1419+
| stringstream.cpp:34:26:34:30 | 456 | stringstream.cpp:34:11:34:11 | ref arg call to operator<< | TAINT |
1420+
| stringstream.cpp:34:26:34:30 | 456 | stringstream.cpp:34:23:34:23 | call to operator<< | TAINT |
14031421
| stringstream.cpp:35:7:35:9 | ref arg ss5 | stringstream.cpp:41:7:41:9 | ss5 | |
14041422
| stringstream.cpp:35:7:35:9 | ref arg ss5 | stringstream.cpp:46:7:46:9 | ss5 | |
1423+
| stringstream.cpp:35:7:35:9 | ss5 | stringstream.cpp:35:11:35:11 | call to operator<< | TAINT |
1424+
| stringstream.cpp:35:14:35:14 | t | stringstream.cpp:35:7:35:9 | ref arg ss5 | TAINT |
1425+
| stringstream.cpp:35:14:35:14 | t | stringstream.cpp:35:11:35:11 | call to operator<< | TAINT |
14051426
| stringstream.cpp:48:2:48:4 | ref arg ss6 | stringstream.cpp:49:2:49:4 | ss6 | |
14061427
| stringstream.cpp:48:2:48:4 | ref arg ss6 | stringstream.cpp:52:7:52:9 | ss6 | |
14071428
| stringstream.cpp:48:10:48:14 | abc | stringstream.cpp:48:10:48:14 | call to basic_string | TAINT |
@@ -1434,9 +1455,15 @@
14341455
| stringstream.cpp:75:7:75:9 | ref arg ss1 | stringstream.cpp:77:7:77:9 | ss1 | |
14351456
| stringstream.cpp:75:7:75:9 | ref arg ss1 | stringstream.cpp:80:7:80:9 | ss1 | |
14361457
| stringstream.cpp:75:7:75:9 | ref arg ss1 | stringstream.cpp:82:7:82:9 | ss1 | |
1458+
| stringstream.cpp:75:7:75:9 | ss1 | stringstream.cpp:75:11:75:11 | call to operator<< | TAINT |
1459+
| stringstream.cpp:75:14:75:17 | 1234 | stringstream.cpp:75:7:75:9 | ref arg ss1 | TAINT |
1460+
| stringstream.cpp:75:14:75:17 | 1234 | stringstream.cpp:75:11:75:11 | call to operator<< | TAINT |
14371461
| stringstream.cpp:76:7:76:9 | ref arg ss2 | stringstream.cpp:78:7:78:9 | ss2 | |
14381462
| stringstream.cpp:76:7:76:9 | ref arg ss2 | stringstream.cpp:81:7:81:9 | ss2 | |
14391463
| stringstream.cpp:76:7:76:9 | ref arg ss2 | stringstream.cpp:83:7:83:9 | ss2 | |
1464+
| stringstream.cpp:76:7:76:9 | ss2 | stringstream.cpp:76:11:76:11 | call to operator<< | TAINT |
1465+
| stringstream.cpp:76:14:76:19 | source | stringstream.cpp:76:7:76:9 | ref arg ss2 | TAINT |
1466+
| stringstream.cpp:76:14:76:19 | source | stringstream.cpp:76:11:76:11 | call to operator<< | TAINT |
14401467
| stringstream.cpp:77:7:77:9 | ref arg ss1 | stringstream.cpp:80:7:80:9 | ss1 | |
14411468
| stringstream.cpp:77:7:77:9 | ref arg ss1 | stringstream.cpp:82:7:82:9 | ss1 | |
14421469
| stringstream.cpp:77:14:77:15 | ref arg v1 | stringstream.cpp:84:7:84:8 | v1 | |
@@ -1551,6 +1578,9 @@
15511578
| stringstream.cpp:142:7:142:9 | ref arg ss1 | stringstream.cpp:174:12:174:14 | ss1 | |
15521579
| stringstream.cpp:142:7:142:9 | ref arg ss1 | stringstream.cpp:176:12:176:14 | ss1 | |
15531580
| stringstream.cpp:142:7:142:9 | ref arg ss1 | stringstream.cpp:178:7:178:9 | ss1 | |
1581+
| stringstream.cpp:142:7:142:9 | ss1 | stringstream.cpp:142:11:142:11 | call to operator<< | TAINT |
1582+
| stringstream.cpp:142:14:142:18 | abc | stringstream.cpp:142:7:142:9 | ref arg ss1 | TAINT |
1583+
| stringstream.cpp:142:14:142:18 | abc | stringstream.cpp:142:11:142:11 | call to operator<< | TAINT |
15541584
| stringstream.cpp:143:7:143:9 | ref arg ss2 | stringstream.cpp:146:7:146:9 | ss2 | |
15551585
| stringstream.cpp:143:7:143:9 | ref arg ss2 | stringstream.cpp:147:7:147:9 | ss2 | |
15561586
| stringstream.cpp:143:7:143:9 | ref arg ss2 | stringstream.cpp:154:7:154:9 | ss2 | |
@@ -1561,6 +1591,9 @@
15611591
| stringstream.cpp:143:7:143:9 | ref arg ss2 | stringstream.cpp:175:12:175:14 | ss2 | |
15621592
| stringstream.cpp:143:7:143:9 | ref arg ss2 | stringstream.cpp:177:12:177:14 | ss2 | |
15631593
| stringstream.cpp:143:7:143:9 | ref arg ss2 | stringstream.cpp:179:7:179:9 | ss2 | |
1594+
| stringstream.cpp:143:7:143:9 | ss2 | stringstream.cpp:143:11:143:11 | call to operator<< | TAINT |
1595+
| stringstream.cpp:143:14:143:19 | call to source | stringstream.cpp:143:7:143:9 | ref arg ss2 | TAINT |
1596+
| stringstream.cpp:143:14:143:19 | call to source | stringstream.cpp:143:11:143:11 | call to operator<< | TAINT |
15641597
| stringstream.cpp:145:7:145:9 | ref arg ss1 | stringstream.cpp:153:7:153:9 | ss1 | |
15651598
| stringstream.cpp:145:7:145:9 | ref arg ss1 | stringstream.cpp:161:7:161:9 | ss1 | |
15661599
| stringstream.cpp:145:7:145:9 | ref arg ss1 | stringstream.cpp:163:7:163:9 | ss1 | |

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

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,16 @@ void test_stringstream_string(int amount)
2929
std::string t(source());
3030

3131
sink(ss1 << "1234");
32-
sink(ss2 << source()); // tainted [NOT DETECTED]
33-
sink(ss3 << "123" << source()); // tainted [NOT DETECTED]
34-
sink(ss4 << source() << "456"); // tainted [NOT DETECTED]
35-
sink(ss5 << t); // tainted [NOT DETECTED]
32+
sink(ss2 << source()); // tainted
33+
sink(ss3 << "123" << source()); // tainted
34+
sink(ss4 << source() << "456"); // tainted
35+
sink(ss5 << t); // tainted
3636

3737
sink(ss1);
38-
sink(ss2); // tainted [NOT DETECTED]
38+
sink(ss2); // tainted
3939
sink(ss3); // tainted [NOT DETECTED]
40-
sink(ss4); // tainted [NOT DETECTED]
41-
sink(ss5); // tainted [NOT DETECTED]
40+
sink(ss4); // tainted
41+
sink(ss5); // tainted
4242
sink(ss1.str());
4343
sink(ss2.str()); // tainted [NOT DETECTED]
4444
sink(ss3.str()); // tainted [NOT DETECTED]
@@ -73,12 +73,12 @@ void test_stringstream_int(int source)
7373
int v1 = 0, v2 = 0;
7474

7575
sink(ss1 << 1234);
76-
sink(ss2 << source); // tainted [NOT DETECTED]
76+
sink(ss2 << source); // tainted
7777
sink(ss1 >> v1);
7878
sink(ss2 >> v2); // tainted [NOT DETECTED]
7979

8080
sink(ss1);
81-
sink(ss2); // tainted [NOT DETECTED]
81+
sink(ss2); // tainted
8282
sink(ss1.str());
8383
sink(ss2.str()); // tainted [NOT DETECTED]
8484
sink(v1);
@@ -140,7 +140,7 @@ void test_stringstream_in()
140140
char c1 = 0, c2 = 0, c3 = 0, c4 = 0, c5 = 0, c6 = 0;
141141

142142
sink(ss1 << "abc");
143-
sink(ss2 << source()); // tainted [NOT DETECTED]
143+
sink(ss2 << source()); // tainted
144144

145145
sink(ss1 >> s1);
146146
sink(ss2 >> s2); // tainted [NOT DETECTED]

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,16 @@
156156
| string.cpp:555:8:555:8 | d | string.cpp:549:27:549:32 | call to source |
157157
| string.cpp:556:8:556:8 | e | string.cpp:550:31:550:36 | call to source |
158158
| string.cpp:557:8:557:8 | f | string.cpp:551:18:551:23 | call to source |
159+
| stringstream.cpp:32:11:32:11 | call to operator<< | stringstream.cpp:32:14:32:19 | call to source |
160+
| stringstream.cpp:33:20:33:20 | call to operator<< | stringstream.cpp:33:23:33:28 | call to source |
161+
| stringstream.cpp:34:23:34:23 | call to operator<< | stringstream.cpp:34:14:34:19 | call to source |
162+
| stringstream.cpp:35:11:35:11 | call to operator<< | stringstream.cpp:29:16:29:21 | call to source |
163+
| stringstream.cpp:38:7:38:9 | ss2 | stringstream.cpp:32:14:32:19 | call to source |
164+
| stringstream.cpp:40:7:40:9 | ss4 | stringstream.cpp:34:14:34:19 | call to source |
165+
| stringstream.cpp:41:7:41:9 | ss5 | stringstream.cpp:29:16:29:21 | call to source |
166+
| stringstream.cpp:76:11:76:11 | call to operator<< | stringstream.cpp:70:32:70:37 | source |
167+
| stringstream.cpp:81:7:81:9 | ss2 | stringstream.cpp:70:32:70:37 | source |
168+
| stringstream.cpp:143:11:143:11 | call to operator<< | stringstream.cpp:143:14:143:19 | call to source |
159169
| structlikeclass.cpp:35:8:35:9 | s1 | structlikeclass.cpp:29:22:29:27 | call to source |
160170
| structlikeclass.cpp:36:8:36:9 | s2 | structlikeclass.cpp:30:24:30:29 | call to source |
161171
| structlikeclass.cpp:37:8:37:9 | s3 | structlikeclass.cpp:29:22:29:27 | call to source |

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,16 @@
166166
| string.cpp:555:8:555:8 | string.cpp:549:27:549:32 | AST only |
167167
| string.cpp:556:8:556:8 | string.cpp:550:31:550:36 | AST only |
168168
| string.cpp:557:8:557:8 | string.cpp:551:18:551:23 | AST only |
169+
| stringstream.cpp:32:11:32:11 | stringstream.cpp:32:14:32:19 | AST only |
170+
| stringstream.cpp:33:20:33:20 | stringstream.cpp:33:23:33:28 | AST only |
171+
| stringstream.cpp:34:23:34:23 | stringstream.cpp:34:14:34:19 | AST only |
172+
| stringstream.cpp:35:11:35:11 | stringstream.cpp:29:16:29:21 | AST only |
173+
| stringstream.cpp:38:7:38:9 | stringstream.cpp:32:14:32:19 | AST only |
174+
| stringstream.cpp:40:7:40:9 | stringstream.cpp:34:14:34:19 | AST only |
175+
| stringstream.cpp:41:7:41:9 | stringstream.cpp:29:16:29:21 | AST only |
176+
| stringstream.cpp:76:11:76:11 | stringstream.cpp:70:32:70:37 | AST only |
177+
| stringstream.cpp:81:7:81:9 | stringstream.cpp:70:32:70:37 | AST only |
178+
| stringstream.cpp:143:11:143:11 | stringstream.cpp:143:14:143:19 | AST only |
169179
| structlikeclass.cpp:35:8:35:9 | structlikeclass.cpp:29:22:29:27 | AST only |
170180
| structlikeclass.cpp:36:8:36:9 | structlikeclass.cpp:30:24:30:29 | AST only |
171181
| structlikeclass.cpp:37:8:37:9 | structlikeclass.cpp:29:22:29:27 | AST only |

0 commit comments

Comments
 (0)