Skip to content

Commit 031c9b9

Browse files
committed
C++: General taint flow through constructors.
1 parent 30151c9 commit 031c9b9

File tree

8 files changed

+135
-16
lines changed

8 files changed

+135
-16
lines changed

cpp/ql/src/semmle/code/cpp/MemberFunction.qll

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
*/
55

66
import cpp
7+
import semmle.code.cpp.models.interfaces.DataFlow
8+
import semmle.code.cpp.models.interfaces.Taint
79

810
/**
911
* A C++ function declared as a member of a class [N4140 9.3]. This includes
@@ -162,7 +164,7 @@ class ConstMemberFunction extends MemberFunction {
162164
* };
163165
* ```
164166
*/
165-
class Constructor extends MemberFunction {
167+
class Constructor extends MemberFunction, TaintFunction {
166168
Constructor() { functions(underlyingElement(this), _, 2) }
167169

168170
override string getCanonicalQLClass() { result = "Constructor" }
@@ -192,6 +194,12 @@ class Constructor extends MemberFunction {
192194
ConstructorInit getInitializer(int i) {
193195
exprparents(unresolveElement(result), i, underlyingElement(this))
194196
}
197+
198+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
199+
// taint flow from any constructor argument to the returned object
200+
input.isParameter(_) and
201+
output.isReturnValue()
202+
}
195203
}
196204

197205
/**

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ void test_copyableclass()
3636
MyCopyableClass s4;
3737
s4 = source();
3838

39-
sink(s1); // tainted [NOT DETECTED]
40-
sink(s2); // tainted [NOT DETECTED]
41-
sink(s3); // tainted [NOT DETECTED]
39+
sink(s1); // tainted
40+
sink(s2); // tainted
41+
sink(s3); // tainted
4242
sink(s4); // tainted [NOT DETECTED]
4343
}
4444

@@ -61,7 +61,7 @@ void test_copyableclass()
6161
MyCopyableClass s3;
6262
s2 = MyCopyableClass(source());
6363

64-
sink(s1); // tainted [NOT DETECTED]
64+
sink(s1); // tainted
6565
sink(s2); // tainted [NOT DETECTED]
6666
sink(s3 = source()); // tainted [NOT DETECTED]
6767
}

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

Lines changed: 57 additions & 0 deletions
Large diffs are not rendered by default.

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ void test_copyableclass()
4040
MyMovableClass s3;
4141
s3 = source();
4242

43-
sink(s1); // tainted [NOT DETECTED]
44-
sink(s2); // tainted [NOT DETECTED]
43+
sink(s1); // tainted
44+
sink(s2); // tainted
4545
sink(s3); // tainted [NOT DETECTED]
4646
}
4747

@@ -50,7 +50,7 @@ void test_copyableclass()
5050
MyMovableClass s2;
5151
s2 = MyMovableClass(source());
5252

53-
sink(s1); // tainted [NOT DETECTED]
53+
sink(s1); // tainted
5454
sink(s2); // tainted [NOT DETECTED]
5555
}
5656

@@ -60,7 +60,7 @@ void test_copyableclass()
6060
MyMovableClass s3;
6161

6262
sink(s1);
63-
sink(s2); // tainted [NOT DETECTED]
63+
sink(s2); // tainted
6464
sink(s3 = source()); // tainted [NOT DETECTED]
6565
}
6666
}

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ void test_structlikeclass()
3131
StructLikeClass s4;
3232
s4 = source();
3333

34-
sink(s1); // tainted [NOT DETECTED]
35-
sink(s2); // tainted [NOT DETECTED]
36-
sink(s3); // tainted [NOT DETECTED]
37-
sink(s4); // tainted [NOT DETECTED]
34+
sink(s1); // tainted
35+
sink(s2); // tainted
36+
sink(s3); // tainted
37+
sink(s4); // tainted
3838
}
3939

4040
{
@@ -56,8 +56,8 @@ void test_structlikeclass()
5656
StructLikeClass s3;
5757
s2 = StructLikeClass(source());
5858

59-
sink(s1); // tainted [NOT DETECTED]
60-
sink(s2); // tainted [NOT DETECTED]
61-
sink(s3 = source()); // tainted [NOT DETECTED]
59+
sink(s1); // tainted
60+
sink(s2); // tainted
61+
sink(s3 = source()); // tainted
6262
}
6363
}

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
| copyableclass.cpp:39:8:39:9 | s1 | copyableclass.cpp:33:22:33:27 | call to source |
2+
| copyableclass.cpp:40:8:40:9 | s2 | copyableclass.cpp:34:24:34:29 | call to source |
3+
| copyableclass.cpp:41:8:41:9 | s3 | copyableclass.cpp:33:22:33:27 | call to source |
4+
| copyableclass.cpp:64:8:64:9 | s1 | copyableclass.cpp:59:40:59:45 | call to source |
15
| format.cpp:57:8:57:13 | buffer | format.cpp:56:36:56:49 | call to source |
26
| format.cpp:62:8:62:13 | buffer | format.cpp:61:30:61:43 | call to source |
37
| format.cpp:67:8:67:13 | buffer | format.cpp:66:52:66:65 | call to source |
@@ -10,8 +14,30 @@
1014
| format.cpp:110:8:110:14 | wbuffer | format.cpp:109:38:109:52 | call to source |
1115
| format.cpp:157:7:157:22 | access to array | format.cpp:147:12:147:25 | call to source |
1216
| format.cpp:158:7:158:27 | ... + ... | format.cpp:148:16:148:30 | call to source |
17+
| movableclass.cpp:43:8:43:9 | s1 | movableclass.cpp:38:21:38:26 | call to source |
18+
| movableclass.cpp:44:8:44:9 | s2 | movableclass.cpp:39:23:39:28 | call to source |
19+
| movableclass.cpp:53:8:53:9 | s1 | movableclass.cpp:49:38:49:43 | call to source |
20+
| movableclass.cpp:63:8:63:9 | s2 | movableclass.cpp:22:55:22:60 | call to source |
1321
| stl.cpp:71:7:71:7 | a | stl.cpp:67:12:67:17 | call to source |
22+
| stl.cpp:73:7:73:7 | c | stl.cpp:69:16:69:21 | call to source |
23+
| stl.cpp:75:9:75:13 | call to c_str | stl.cpp:69:16:69:21 | call to source |
24+
| stl.cpp:125:13:125:17 | call to c_str | stl.cpp:117:10:117:15 | call to source |
25+
| stl.cpp:129:13:129:17 | call to c_str | stl.cpp:117:10:117:15 | call to source |
26+
| stl.cpp:132:13:132:17 | call to c_str | stl.cpp:117:10:117:15 | call to source |
27+
| stl.cpp:154:8:154:9 | s1 | stl.cpp:149:18:149:23 | call to source |
28+
| stl.cpp:155:8:155:9 | s2 | stl.cpp:150:20:150:25 | call to source |
29+
| stl.cpp:156:8:156:9 | s3 | stl.cpp:152:8:152:13 | call to source |
30+
| stl.cpp:175:8:175:9 | s1 | stl.cpp:171:32:171:37 | call to source |
31+
| stl.cpp:176:8:176:9 | s2 | stl.cpp:173:20:173:25 | call to source |
32+
| structlikeclass.cpp:34:8:34:9 | s1 | structlikeclass.cpp:28:22:28:27 | call to source |
33+
| structlikeclass.cpp:35:8:35:9 | s2 | structlikeclass.cpp:29:24:29:29 | call to source |
34+
| structlikeclass.cpp:36:8:36:9 | s3 | structlikeclass.cpp:28:22:28:27 | call to source |
35+
| structlikeclass.cpp:37:8:37:9 | s4 | structlikeclass.cpp:32:8:32:13 | call to source |
36+
| structlikeclass.cpp:59:8:59:9 | s1 | structlikeclass.cpp:54:40:54:45 | call to source |
37+
| structlikeclass.cpp:60:8:60:9 | s2 | structlikeclass.cpp:57:24:57:29 | call to source |
38+
| structlikeclass.cpp:61:8:61:20 | ... = ... | structlikeclass.cpp:61:13:61:18 | call to source |
1439
| swap1.cpp:60:12:60:16 | data1 | swap1.cpp:58:15:58:20 | call to source |
40+
| swap1.cpp:65:12:65:16 | data1 | swap1.cpp:56:23:56:23 | x |
1541
| swap1.cpp:65:12:65:16 | data1 | swap1.cpp:58:15:58:20 | call to source |
1642
| swap1.cpp:66:12:66:16 | data1 | swap1.cpp:58:15:58:20 | call to source |
1743
| swap1.cpp:70:13:70:17 | data1 | swap1.cpp:69:16:69:21 | call to source |
@@ -26,6 +52,7 @@
2652
| swap1.cpp:102:18:102:22 | data1 | swap1.cpp:95:23:95:31 | move_from |
2753
| swap1.cpp:102:18:102:22 | data1 | swap1.cpp:96:23:96:28 | call to source |
2854
| swap2.cpp:60:12:60:16 | data1 | swap2.cpp:58:15:58:20 | call to source |
55+
| swap2.cpp:65:12:65:16 | data1 | swap2.cpp:56:23:56:23 | x |
2956
| swap2.cpp:65:12:65:16 | data1 | swap2.cpp:58:15:58:20 | call to source |
3057
| swap2.cpp:66:12:66:16 | data1 | swap2.cpp:58:15:58:20 | call to source |
3158
| swap2.cpp:70:13:70:17 | data1 | swap2.cpp:69:16:69:21 | call to source |

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
| copyableclass.cpp:39:8:39:9 | copyableclass.cpp:33:22:33:27 | AST only |
2+
| copyableclass.cpp:40:8:40:9 | copyableclass.cpp:34:24:34:29 | AST only |
3+
| copyableclass.cpp:41:8:41:9 | copyableclass.cpp:33:22:33:27 | AST only |
4+
| copyableclass.cpp:64:8:64:9 | copyableclass.cpp:59:40:59:45 | AST only |
15
| format.cpp:57:8:57:13 | format.cpp:56:36:56:49 | AST only |
26
| format.cpp:62:8:62:13 | format.cpp:61:30:61:43 | AST only |
37
| format.cpp:67:8:67:13 | format.cpp:66:52:66:65 | AST only |
@@ -8,10 +12,30 @@
812
| format.cpp:100:8:100:13 | format.cpp:99:30:99:43 | AST only |
913
| format.cpp:105:8:105:13 | format.cpp:104:31:104:45 | AST only |
1014
| format.cpp:110:8:110:14 | format.cpp:109:38:109:52 | AST only |
15+
| movableclass.cpp:43:8:43:9 | movableclass.cpp:38:21:38:26 | AST only |
16+
| movableclass.cpp:44:8:44:9 | movableclass.cpp:39:23:39:28 | AST only |
17+
| movableclass.cpp:53:8:53:9 | movableclass.cpp:49:38:49:43 | AST only |
18+
| movableclass.cpp:63:8:63:9 | movableclass.cpp:22:55:22:60 | AST only |
19+
| stl.cpp:73:7:73:7 | stl.cpp:69:16:69:21 | AST only |
20+
| stl.cpp:75:9:75:13 | stl.cpp:69:16:69:21 | AST only |
21+
| stl.cpp:125:13:125:17 | stl.cpp:117:10:117:15 | AST only |
22+
| stl.cpp:129:13:129:17 | stl.cpp:117:10:117:15 | AST only |
23+
| stl.cpp:132:13:132:17 | stl.cpp:117:10:117:15 | AST only |
24+
| stl.cpp:154:8:154:9 | stl.cpp:149:18:149:23 | AST only |
25+
| stl.cpp:155:8:155:9 | stl.cpp:150:20:150:25 | AST only |
26+
| stl.cpp:156:8:156:9 | stl.cpp:152:8:152:13 | AST only |
27+
| stl.cpp:175:8:175:9 | stl.cpp:171:32:171:37 | AST only |
28+
| stl.cpp:176:8:176:9 | stl.cpp:173:20:173:25 | AST only |
29+
| structlikeclass.cpp:34:8:34:9 | structlikeclass.cpp:28:22:28:27 | AST only |
30+
| structlikeclass.cpp:35:8:35:9 | structlikeclass.cpp:29:24:29:29 | AST only |
31+
| structlikeclass.cpp:36:8:36:9 | structlikeclass.cpp:28:22:28:27 | AST only |
32+
| structlikeclass.cpp:59:8:59:9 | structlikeclass.cpp:54:40:54:45 | AST only |
33+
| swap1.cpp:65:12:65:16 | swap1.cpp:56:23:56:23 | AST only |
1134
| swap1.cpp:74:13:74:17 | swap1.cpp:69:16:69:21 | AST only |
1235
| swap1.cpp:75:13:75:17 | swap1.cpp:68:27:68:28 | AST only |
1336
| swap1.cpp:89:12:89:16 | swap1.cpp:80:23:80:23 | AST only |
1437
| swap1.cpp:102:18:102:22 | swap1.cpp:95:23:95:31 | AST only |
38+
| swap2.cpp:65:12:65:16 | swap2.cpp:56:23:56:23 | AST only |
1539
| swap2.cpp:74:13:74:17 | swap2.cpp:69:16:69:21 | AST only |
1640
| swap2.cpp:75:13:75:17 | swap2.cpp:68:27:68:28 | AST only |
1741
| swap2.cpp:89:12:89:16 | swap2.cpp:80:23:80:23 | AST only |

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
| format.cpp:158:7:158:27 | ... + ... | format.cpp:148:16:148:30 | call to source |
44
| stl.cpp:71:7:71:7 | (const char *)... | stl.cpp:67:12:67:17 | call to source |
55
| stl.cpp:71:7:71:7 | a | stl.cpp:67:12:67:17 | call to source |
6+
| structlikeclass.cpp:37:8:37:9 | s4 | structlikeclass.cpp:32:8:32:13 | call to source |
7+
| structlikeclass.cpp:60:8:60:9 | s2 | structlikeclass.cpp:57:24:57:29 | call to source |
8+
| structlikeclass.cpp:61:8:61:20 | ... = ... | structlikeclass.cpp:61:13:61:18 | call to source |
69
| swap1.cpp:60:12:60:16 | data1 | swap1.cpp:58:15:58:20 | call to source |
710
| swap1.cpp:65:12:65:16 | data1 | swap1.cpp:58:15:58:20 | call to source |
811
| swap1.cpp:66:12:66:16 | data1 | swap1.cpp:58:15:58:20 | call to source |

0 commit comments

Comments
 (0)