Skip to content

Commit 23030aa

Browse files
authored
Merge pull request #2706 from MathiasVP/ql-tests-taint-tracking
Ql tests for virtual dispatch taint tracking
2 parents 8c00671 + 611d955 commit 23030aa

File tree

4 files changed

+270
-0
lines changed

4 files changed

+270
-0
lines changed

cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/tainted.expected

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
| defaulttainttracking.cpp:16:16:16:21 | call to getenv | defaulttainttracking.cpp:16:8:16:29 | (const char *)... |
55
| defaulttainttracking.cpp:16:16:16:21 | call to getenv | defaulttainttracking.cpp:16:16:16:21 | call to getenv |
66
| defaulttainttracking.cpp:16:16:16:21 | call to getenv | defaulttainttracking.cpp:16:16:16:28 | (const char *)... |
7+
| defaulttainttracking.cpp:16:16:16:21 | call to getenv | test_diff.cpp:1:11:1:20 | p#0 |
78
| defaulttainttracking.cpp:17:15:17:20 | call to getenv | defaulttainttracking.cpp:5:14:5:23 | p#0 |
89
| defaulttainttracking.cpp:17:15:17:20 | call to getenv | defaulttainttracking.cpp:9:11:9:20 | p#0 |
910
| defaulttainttracking.cpp:17:15:17:20 | call to getenv | defaulttainttracking.cpp:17:8:17:13 | call to strdup |
1011
| defaulttainttracking.cpp:17:15:17:20 | call to getenv | defaulttainttracking.cpp:17:8:17:28 | (const char *)... |
1112
| defaulttainttracking.cpp:17:15:17:20 | call to getenv | defaulttainttracking.cpp:17:15:17:20 | call to getenv |
1213
| defaulttainttracking.cpp:17:15:17:20 | call to getenv | defaulttainttracking.cpp:17:15:17:27 | (const char *)... |
14+
| defaulttainttracking.cpp:17:15:17:20 | call to getenv | test_diff.cpp:1:11:1:20 | p#0 |
1315
| defaulttainttracking.cpp:18:27:18:32 | call to getenv | defaulttainttracking.cpp:7:26:7:35 | p#0 |
1416
| defaulttainttracking.cpp:18:27:18:32 | call to getenv | defaulttainttracking.cpp:18:27:18:32 | call to getenv |
1517
| defaulttainttracking.cpp:18:27:18:32 | call to getenv | defaulttainttracking.cpp:18:27:18:39 | (const char *)... |
@@ -19,6 +21,7 @@
1921
| defaulttainttracking.cpp:22:20:22:25 | call to getenv | defaulttainttracking.cpp:22:8:22:33 | (const char *)... |
2022
| defaulttainttracking.cpp:22:20:22:25 | call to getenv | defaulttainttracking.cpp:22:20:22:25 | call to getenv |
2123
| defaulttainttracking.cpp:22:20:22:25 | call to getenv | defaulttainttracking.cpp:22:20:22:32 | (const char *)... |
24+
| defaulttainttracking.cpp:22:20:22:25 | call to getenv | test_diff.cpp:1:11:1:20 | p#0 |
2225
| defaulttainttracking.cpp:38:25:38:30 | call to getenv | defaulttainttracking.cpp:32:11:32:26 | p#0 |
2326
| defaulttainttracking.cpp:38:25:38:30 | call to getenv | defaulttainttracking.cpp:38:11:38:21 | env_pointer |
2427
| defaulttainttracking.cpp:38:25:38:30 | call to getenv | defaulttainttracking.cpp:38:25:38:30 | call to getenv |
@@ -27,3 +30,100 @@
2730
| defaulttainttracking.cpp:38:25:38:30 | call to getenv | defaulttainttracking.cpp:39:26:39:34 | call to inet_addr |
2831
| defaulttainttracking.cpp:38:25:38:30 | call to getenv | defaulttainttracking.cpp:39:50:39:61 | & ... |
2932
| defaulttainttracking.cpp:38:25:38:30 | call to getenv | defaulttainttracking.cpp:40:10:40:10 | a |
33+
| test_diff.cpp:92:10:92:13 | argv | defaulttainttracking.cpp:9:11:9:20 | p#0 |
34+
| test_diff.cpp:92:10:92:13 | argv | test_diff.cpp:1:11:1:20 | p#0 |
35+
| test_diff.cpp:92:10:92:13 | argv | test_diff.cpp:92:10:92:13 | argv |
36+
| test_diff.cpp:92:10:92:13 | argv | test_diff.cpp:92:10:92:16 | (const char *)... |
37+
| test_diff.cpp:92:10:92:13 | argv | test_diff.cpp:92:10:92:16 | access to array |
38+
| test_diff.cpp:94:32:94:35 | argv | defaulttainttracking.cpp:10:11:10:13 | p#0 |
39+
| test_diff.cpp:94:32:94:35 | argv | test_diff.cpp:2:11:2:13 | p#0 |
40+
| test_diff.cpp:94:32:94:35 | argv | test_diff.cpp:94:10:94:36 | reinterpret_cast<int>... |
41+
| test_diff.cpp:94:32:94:35 | argv | test_diff.cpp:94:32:94:35 | argv |
42+
| test_diff.cpp:96:26:96:29 | argv | defaulttainttracking.cpp:9:11:9:20 | p#0 |
43+
| test_diff.cpp:96:26:96:29 | argv | test_diff.cpp:1:11:1:20 | p#0 |
44+
| test_diff.cpp:96:26:96:29 | argv | test_diff.cpp:16:39:16:39 | a |
45+
| test_diff.cpp:96:26:96:29 | argv | test_diff.cpp:17:10:17:10 | a |
46+
| test_diff.cpp:96:26:96:29 | argv | test_diff.cpp:96:26:96:29 | argv |
47+
| test_diff.cpp:96:26:96:29 | argv | test_diff.cpp:96:26:96:32 | (const char *)... |
48+
| test_diff.cpp:96:26:96:29 | argv | test_diff.cpp:96:26:96:32 | access to array |
49+
| test_diff.cpp:98:18:98:21 | argv | defaulttainttracking.cpp:9:11:9:20 | p#0 |
50+
| test_diff.cpp:98:18:98:21 | argv | test_diff.cpp:1:11:1:20 | p#0 |
51+
| test_diff.cpp:98:18:98:21 | argv | test_diff.cpp:16:39:16:39 | a |
52+
| test_diff.cpp:98:18:98:21 | argv | test_diff.cpp:17:10:17:10 | a |
53+
| test_diff.cpp:98:18:98:21 | argv | test_diff.cpp:98:13:98:13 | p |
54+
| test_diff.cpp:98:18:98:21 | argv | test_diff.cpp:98:17:98:21 | & ... |
55+
| test_diff.cpp:98:18:98:21 | argv | test_diff.cpp:98:18:98:21 | argv |
56+
| test_diff.cpp:98:18:98:21 | argv | test_diff.cpp:100:10:100:14 | (const char *)... |
57+
| test_diff.cpp:98:18:98:21 | argv | test_diff.cpp:100:10:100:14 | * ... |
58+
| test_diff.cpp:98:18:98:21 | argv | test_diff.cpp:100:11:100:11 | p |
59+
| test_diff.cpp:98:18:98:21 | argv | test_diff.cpp:100:11:100:14 | access to array |
60+
| test_diff.cpp:98:18:98:21 | argv | test_diff.cpp:102:26:102:30 | (const char *)... |
61+
| test_diff.cpp:98:18:98:21 | argv | test_diff.cpp:102:26:102:30 | * ... |
62+
| test_diff.cpp:98:18:98:21 | argv | test_diff.cpp:102:27:102:27 | p |
63+
| test_diff.cpp:98:18:98:21 | argv | test_diff.cpp:102:27:102:30 | access to array |
64+
| test_diff.cpp:104:12:104:15 | argv | defaulttainttracking.cpp:9:11:9:20 | p#0 |
65+
| test_diff.cpp:104:12:104:15 | argv | test_diff.cpp:1:11:1:20 | p#0 |
66+
| test_diff.cpp:104:12:104:15 | argv | test_diff.cpp:104:10:104:20 | (const char *)... |
67+
| test_diff.cpp:104:12:104:15 | argv | test_diff.cpp:104:10:104:20 | * ... |
68+
| test_diff.cpp:104:12:104:15 | argv | test_diff.cpp:104:11:104:20 | (...) |
69+
| test_diff.cpp:104:12:104:15 | argv | test_diff.cpp:104:12:104:15 | argv |
70+
| test_diff.cpp:104:12:104:15 | argv | test_diff.cpp:104:12:104:19 | ... + ... |
71+
| test_diff.cpp:108:10:108:13 | argv | defaulttainttracking.cpp:9:11:9:20 | p#0 |
72+
| test_diff.cpp:108:10:108:13 | argv | test_diff.cpp:1:11:1:20 | p#0 |
73+
| test_diff.cpp:108:10:108:13 | argv | test_diff.cpp:24:20:24:29 | p#0 |
74+
| test_diff.cpp:108:10:108:13 | argv | test_diff.cpp:29:24:29:24 | p |
75+
| test_diff.cpp:108:10:108:13 | argv | test_diff.cpp:30:14:30:14 | p |
76+
| test_diff.cpp:108:10:108:13 | argv | test_diff.cpp:108:10:108:13 | argv |
77+
| test_diff.cpp:108:10:108:13 | argv | test_diff.cpp:108:10:108:16 | (const char *)... |
78+
| test_diff.cpp:108:10:108:13 | argv | test_diff.cpp:108:10:108:16 | access to array |
79+
| test_diff.cpp:111:10:111:13 | argv | test_diff.cpp:24:20:24:29 | p#0 |
80+
| test_diff.cpp:111:10:111:13 | argv | test_diff.cpp:36:24:36:24 | p |
81+
| test_diff.cpp:111:10:111:13 | argv | test_diff.cpp:111:10:111:13 | argv |
82+
| test_diff.cpp:111:10:111:13 | argv | test_diff.cpp:111:10:111:16 | (const char *)... |
83+
| test_diff.cpp:111:10:111:13 | argv | test_diff.cpp:111:10:111:16 | access to array |
84+
| test_diff.cpp:115:11:115:14 | argv | defaulttainttracking.cpp:9:11:9:20 | p#0 |
85+
| test_diff.cpp:115:11:115:14 | argv | test_diff.cpp:1:11:1:20 | p#0 |
86+
| test_diff.cpp:115:11:115:14 | argv | test_diff.cpp:24:20:24:29 | p#0 |
87+
| test_diff.cpp:115:11:115:14 | argv | test_diff.cpp:41:24:41:24 | p |
88+
| test_diff.cpp:115:11:115:14 | argv | test_diff.cpp:42:14:42:14 | p |
89+
| test_diff.cpp:115:11:115:14 | argv | test_diff.cpp:52:24:52:24 | p |
90+
| test_diff.cpp:115:11:115:14 | argv | test_diff.cpp:53:37:53:37 | p |
91+
| test_diff.cpp:115:11:115:14 | argv | test_diff.cpp:115:11:115:14 | argv |
92+
| test_diff.cpp:115:11:115:14 | argv | test_diff.cpp:115:11:115:17 | (const char *)... |
93+
| test_diff.cpp:115:11:115:14 | argv | test_diff.cpp:115:11:115:17 | access to array |
94+
| test_diff.cpp:118:26:118:29 | argv | test_diff.cpp:60:24:60:24 | p |
95+
| test_diff.cpp:118:26:118:29 | argv | test_diff.cpp:61:34:61:34 | p |
96+
| test_diff.cpp:118:26:118:29 | argv | test_diff.cpp:88:24:88:24 | p |
97+
| test_diff.cpp:118:26:118:29 | argv | test_diff.cpp:118:26:118:29 | argv |
98+
| test_diff.cpp:118:26:118:29 | argv | test_diff.cpp:118:26:118:32 | (const char *)... |
99+
| test_diff.cpp:118:26:118:29 | argv | test_diff.cpp:118:26:118:32 | access to array |
100+
| test_diff.cpp:121:23:121:26 | argv | defaulttainttracking.cpp:9:11:9:20 | p#0 |
101+
| test_diff.cpp:121:23:121:26 | argv | test_diff.cpp:1:11:1:20 | p#0 |
102+
| test_diff.cpp:121:23:121:26 | argv | test_diff.cpp:60:24:60:24 | p |
103+
| test_diff.cpp:121:23:121:26 | argv | test_diff.cpp:61:34:61:34 | p |
104+
| test_diff.cpp:121:23:121:26 | argv | test_diff.cpp:67:24:67:24 | p |
105+
| test_diff.cpp:121:23:121:26 | argv | test_diff.cpp:68:14:68:14 | p |
106+
| test_diff.cpp:121:23:121:26 | argv | test_diff.cpp:121:23:121:26 | argv |
107+
| test_diff.cpp:121:23:121:26 | argv | test_diff.cpp:121:23:121:29 | (const char *)... |
108+
| test_diff.cpp:121:23:121:26 | argv | test_diff.cpp:121:23:121:29 | access to array |
109+
| test_diff.cpp:124:19:124:22 | argv | defaulttainttracking.cpp:9:11:9:20 | p#0 |
110+
| test_diff.cpp:124:19:124:22 | argv | test_diff.cpp:1:11:1:20 | p#0 |
111+
| test_diff.cpp:124:19:124:22 | argv | test_diff.cpp:24:20:24:29 | p#0 |
112+
| test_diff.cpp:124:19:124:22 | argv | test_diff.cpp:76:24:76:24 | p |
113+
| test_diff.cpp:124:19:124:22 | argv | test_diff.cpp:81:24:81:24 | p |
114+
| test_diff.cpp:124:19:124:22 | argv | test_diff.cpp:82:14:82:14 | p |
115+
| test_diff.cpp:124:19:124:22 | argv | test_diff.cpp:124:19:124:22 | argv |
116+
| test_diff.cpp:124:19:124:22 | argv | test_diff.cpp:124:19:124:25 | (const char *)... |
117+
| test_diff.cpp:124:19:124:22 | argv | test_diff.cpp:124:19:124:25 | access to array |
118+
| test_diff.cpp:126:43:126:46 | argv | defaulttainttracking.cpp:9:11:9:20 | p#0 |
119+
| test_diff.cpp:126:43:126:46 | argv | test_diff.cpp:1:11:1:20 | p#0 |
120+
| test_diff.cpp:126:43:126:46 | argv | test_diff.cpp:76:24:76:24 | p |
121+
| test_diff.cpp:126:43:126:46 | argv | test_diff.cpp:81:24:81:24 | p |
122+
| test_diff.cpp:126:43:126:46 | argv | test_diff.cpp:82:14:82:14 | p |
123+
| test_diff.cpp:126:43:126:46 | argv | test_diff.cpp:126:43:126:46 | argv |
124+
| test_diff.cpp:126:43:126:46 | argv | test_diff.cpp:126:43:126:49 | (const char *)... |
125+
| test_diff.cpp:126:43:126:46 | argv | test_diff.cpp:126:43:126:49 | access to array |
126+
| test_diff.cpp:128:44:128:47 | argv | test_diff.cpp:76:24:76:24 | p |
127+
| test_diff.cpp:128:44:128:47 | argv | test_diff.cpp:128:44:128:47 | argv |
128+
| test_diff.cpp:128:44:128:47 | argv | test_diff.cpp:128:44:128:50 | (const char *)... |
129+
| test_diff.cpp:128:44:128:47 | argv | test_diff.cpp:128:44:128:50 | access to array |
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
void sink(const char *);
2+
void sink(int);
3+
4+
struct S {
5+
void(*f)(const char*);
6+
7+
void apply(char* p) {
8+
f(p);
9+
}
10+
11+
void (*get())(const char*) {
12+
return f;
13+
}
14+
};
15+
16+
void calls_sink_with_argv(const char* a) {
17+
sink(a);
18+
}
19+
20+
extern int i;
21+
22+
class BaseWithPureVirtual {
23+
public:
24+
virtual void f(const char*) = 0;
25+
};
26+
27+
class DerivedCallsSink : public BaseWithPureVirtual {
28+
public:
29+
void f(const char* p) override {
30+
sink(p);
31+
}
32+
};
33+
34+
class DerivedDoesNotCallSink : public BaseWithPureVirtual {
35+
public:
36+
void f(const char* p) override {}
37+
};
38+
39+
class DerivedCallsSinkDiamond1 : virtual public BaseWithPureVirtual {
40+
public:
41+
void f(const char* p) override {
42+
sink(p);
43+
}
44+
};
45+
46+
class DerivedDoesNotCallSinkDiamond2 : virtual public BaseWithPureVirtual {
47+
public:
48+
void f(const char* p) override {}
49+
};
50+
51+
class DerivesMultiple : public DerivedCallsSinkDiamond1, public DerivedDoesNotCallSinkDiamond2 {
52+
void f(const char* p) override {
53+
DerivedCallsSinkDiamond1::f(p);
54+
}
55+
};
56+
57+
template<typename T>
58+
class CRTP {
59+
public:
60+
void f(const char* p) {
61+
static_cast<T*>(this)->g(p);
62+
}
63+
};
64+
65+
class CRTPCallsSink : public CRTP<CRTPCallsSink> {
66+
public:
67+
void g(const char* p) {
68+
sink(p);
69+
}
70+
};
71+
72+
class Derived1 : public BaseWithPureVirtual {};
73+
74+
class Derived2 : public Derived1 {
75+
public:
76+
void f(const char* p) override {}
77+
};
78+
79+
class Derived3 : public Derived2 {
80+
public:
81+
void f(const char* p) override {
82+
sink(p);
83+
}
84+
};
85+
86+
class CRTPDoesNotCallSink : public CRTP<CRTPDoesNotCallSink> {
87+
public:
88+
void g(const char* p) {}
89+
};
90+
91+
int main(int argc, char *argv[]) {
92+
sink(argv[0]);
93+
94+
sink(reinterpret_cast<int>(argv));
95+
96+
calls_sink_with_argv(argv[1]);
97+
98+
char*** p = &argv;
99+
100+
sink(*p[0]);
101+
102+
calls_sink_with_argv(*p[i]);
103+
104+
sink(*(argv + 1)); // flow [NOT DECTED by AST]
105+
106+
BaseWithPureVirtual* b = new DerivedCallsSink;
107+
108+
b->f(argv[1]); // flow [NOT DETECTED by IR]
109+
110+
b = new DerivedDoesNotCallSink;
111+
b->f(argv[0]); // no flow [FALSE POSITIVE by AST]
112+
113+
BaseWithPureVirtual* b2 = new DerivesMultiple;
114+
115+
b2->f(argv[i]); // flow [NOT DETECTED]
116+
117+
CRTP<CRTPDoesNotCallSink> crtp_not_call_sink;
118+
crtp_not_call_sink.f(argv[0]);
119+
120+
CRTP<CRTPCallsSink> crtp_calls_sink;
121+
crtp_calls_sink.f(argv[0]); // flow [NOT DETECTED]
122+
123+
Derived1* calls_sink = new Derived3;
124+
calls_sink->f(argv[1]); // flow [NOT DETECTED by AST]
125+
126+
static_cast<Derived2*>(calls_sink)->f(argv[1]); // flow [NOT DETECTED]
127+
128+
dynamic_cast<Derived2*>(calls_sink)->f(argv[1]); // flow [NOT DETECTED by IR]
129+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
| defaulttainttracking.cpp:16:16:16:21 | call to getenv | defaulttainttracking.cpp:9:11:9:20 | p#0 | IR only |
2+
| defaulttainttracking.cpp:16:16:16:21 | call to getenv | defaulttainttracking.cpp:16:8:16:14 | call to _strdup | IR only |
3+
| defaulttainttracking.cpp:16:16:16:21 | call to getenv | defaulttainttracking.cpp:16:8:16:29 | (const char *)... | IR only |
4+
| defaulttainttracking.cpp:16:16:16:21 | call to getenv | test_diff.cpp:1:11:1:20 | p#0 | IR only |
5+
| defaulttainttracking.cpp:22:20:22:25 | call to getenv | defaulttainttracking.cpp:3:21:3:22 | s1 | AST only |
6+
| defaulttainttracking.cpp:22:20:22:25 | call to getenv | defaulttainttracking.cpp:21:8:21:10 | buf | AST only |
7+
| defaulttainttracking.cpp:22:20:22:25 | call to getenv | defaulttainttracking.cpp:22:15:22:17 | buf | AST only |
8+
| defaulttainttracking.cpp:22:20:22:25 | call to getenv | defaulttainttracking.cpp:24:8:24:10 | buf | AST only |
9+
| defaulttainttracking.cpp:38:25:38:30 | call to getenv | defaulttainttracking.cpp:31:40:31:53 | dotted_address | AST only |
10+
| defaulttainttracking.cpp:38:25:38:30 | call to getenv | defaulttainttracking.cpp:39:36:39:61 | (const char *)... | AST only |
11+
| defaulttainttracking.cpp:38:25:38:30 | call to getenv | defaulttainttracking.cpp:39:51:39:61 | env_pointer | AST only |
12+
| test_diff.cpp:104:12:104:15 | argv | test_diff.cpp:104:11:104:20 | (...) | IR only |
13+
| test_diff.cpp:108:10:108:13 | argv | test_diff.cpp:36:24:36:24 | p | AST only |
14+
| test_diff.cpp:111:10:111:13 | argv | defaulttainttracking.cpp:9:11:9:20 | p#0 | AST only |
15+
| test_diff.cpp:111:10:111:13 | argv | test_diff.cpp:1:11:1:20 | p#0 | AST only |
16+
| test_diff.cpp:111:10:111:13 | argv | test_diff.cpp:29:24:29:24 | p | AST only |
17+
| test_diff.cpp:111:10:111:13 | argv | test_diff.cpp:30:14:30:14 | p | AST only |
18+
| test_diff.cpp:124:19:124:22 | argv | test_diff.cpp:76:24:76:24 | p | IR only |
19+
| test_diff.cpp:128:44:128:47 | argv | defaulttainttracking.cpp:9:11:9:20 | p#0 | AST only |
20+
| test_diff.cpp:128:44:128:47 | argv | test_diff.cpp:1:11:1:20 | p#0 | AST only |
21+
| test_diff.cpp:128:44:128:47 | argv | test_diff.cpp:81:24:81:24 | p | AST only |
22+
| test_diff.cpp:128:44:128:47 | argv | test_diff.cpp:82:14:82:14 | p | AST only |
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import cpp
2+
import semmle.code.cpp.security.Security
3+
import semmle.code.cpp.security.TaintTracking as ASTTaintTracking
4+
import semmle.code.cpp.ir.dataflow.DefaultTaintTracking as IRDefaultTaintTracking
5+
6+
predicate astFlow(Expr source, Element sink) { ASTTaintTracking::tainted(source, sink) }
7+
8+
predicate irFlow(Expr source, Element sink) { IRDefaultTaintTracking::tainted(source, sink) }
9+
10+
from Expr source, Element sink, string note
11+
where
12+
astFlow(source, sink) and
13+
not irFlow(source, sink) and
14+
note = "AST only"
15+
or
16+
irFlow(source, sink) and
17+
not astFlow(source, sink) and
18+
note = "IR only"
19+
select source, sink, note

0 commit comments

Comments
 (0)