Skip to content

Commit f2402c5

Browse files
committed
C++: Test virtual dispatch field conflation
This test demonstrates that IR data flow conflates unrelated fields of a global struct-typed variable and that this bug is not present in the old AST-based implementation of `semmle.code.cpp.security.TaintTracking`.
1 parent cc00f0f commit f2402c5

File tree

3 files changed

+76
-0
lines changed

3 files changed

+76
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#include "shared.h"
2+
3+
using SinkFunction = void (*)(int);
4+
5+
void notSink(int notSinkParam);
6+
7+
void callsSink(int sinkParam) {
8+
sink(sinkParam);
9+
}
10+
11+
struct {
12+
SinkFunction sinkPtr, notSinkPtr;
13+
} globalStruct;
14+
15+
union {
16+
SinkFunction sinkPtr, notSinkPtr;
17+
} globalUnion;
18+
19+
SinkFunction globalSinkPtr;
20+
21+
void assignGlobals() {
22+
globalStruct.sinkPtr = callsSink;
23+
globalUnion.sinkPtr = callsSink;
24+
globalSinkPtr = callsSink;
25+
};
26+
27+
void testStruct() {
28+
globalStruct.sinkPtr(atoi(getenv("TAINTED"))); // should reach sinkParam [NOT DETECTED in AST]
29+
globalStruct.notSinkPtr(atoi(getenv("TAINTED"))); // shouldn't reach sinkParam [FALSE POSITIVE in IR]
30+
31+
globalUnion.sinkPtr(atoi(getenv("TAINTED"))); // should reach sinkParam
32+
globalUnion.notSinkPtr(atoi(getenv("TAINTED"))); // should reach sinkParam
33+
34+
globalSinkPtr(atoi(getenv("TAINTED"))); // should reach sinkParam
35+
}

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

+35
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,41 @@
9898
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:98:10:98:11 | (const char *)... |
9999
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:98:10:98:11 | p2 |
100100
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | shared.h:5:23:5:31 | sinkparam |
101+
| dispatch.cpp:28:29:28:34 | call to getenv | dispatch.cpp:7:20:7:28 | sinkParam |
102+
| dispatch.cpp:28:29:28:34 | call to getenv | dispatch.cpp:8:8:8:16 | sinkParam |
103+
| dispatch.cpp:28:29:28:34 | call to getenv | dispatch.cpp:28:24:28:27 | call to atoi |
104+
| dispatch.cpp:28:29:28:34 | call to getenv | dispatch.cpp:28:29:28:34 | call to getenv |
105+
| dispatch.cpp:28:29:28:34 | call to getenv | dispatch.cpp:28:29:28:45 | (const char *)... |
106+
| dispatch.cpp:28:29:28:34 | call to getenv | shared.h:6:15:6:23 | sinkparam |
107+
| dispatch.cpp:28:29:28:34 | call to getenv | shared.h:8:22:8:25 | nptr |
108+
| dispatch.cpp:29:32:29:37 | call to getenv | dispatch.cpp:7:20:7:28 | sinkParam |
109+
| dispatch.cpp:29:32:29:37 | call to getenv | dispatch.cpp:8:8:8:16 | sinkParam |
110+
| dispatch.cpp:29:32:29:37 | call to getenv | dispatch.cpp:29:27:29:30 | call to atoi |
111+
| dispatch.cpp:29:32:29:37 | call to getenv | dispatch.cpp:29:32:29:37 | call to getenv |
112+
| dispatch.cpp:29:32:29:37 | call to getenv | dispatch.cpp:29:32:29:48 | (const char *)... |
113+
| dispatch.cpp:29:32:29:37 | call to getenv | shared.h:6:15:6:23 | sinkparam |
114+
| dispatch.cpp:29:32:29:37 | call to getenv | shared.h:8:22:8:25 | nptr |
115+
| dispatch.cpp:31:28:31:33 | call to getenv | dispatch.cpp:7:20:7:28 | sinkParam |
116+
| dispatch.cpp:31:28:31:33 | call to getenv | dispatch.cpp:8:8:8:16 | sinkParam |
117+
| dispatch.cpp:31:28:31:33 | call to getenv | dispatch.cpp:31:23:31:26 | call to atoi |
118+
| dispatch.cpp:31:28:31:33 | call to getenv | dispatch.cpp:31:28:31:33 | call to getenv |
119+
| dispatch.cpp:31:28:31:33 | call to getenv | dispatch.cpp:31:28:31:44 | (const char *)... |
120+
| dispatch.cpp:31:28:31:33 | call to getenv | shared.h:6:15:6:23 | sinkparam |
121+
| dispatch.cpp:31:28:31:33 | call to getenv | shared.h:8:22:8:25 | nptr |
122+
| dispatch.cpp:32:31:32:36 | call to getenv | dispatch.cpp:7:20:7:28 | sinkParam |
123+
| dispatch.cpp:32:31:32:36 | call to getenv | dispatch.cpp:8:8:8:16 | sinkParam |
124+
| dispatch.cpp:32:31:32:36 | call to getenv | dispatch.cpp:32:26:32:29 | call to atoi |
125+
| dispatch.cpp:32:31:32:36 | call to getenv | dispatch.cpp:32:31:32:36 | call to getenv |
126+
| dispatch.cpp:32:31:32:36 | call to getenv | dispatch.cpp:32:31:32:47 | (const char *)... |
127+
| dispatch.cpp:32:31:32:36 | call to getenv | shared.h:6:15:6:23 | sinkparam |
128+
| dispatch.cpp:32:31:32:36 | call to getenv | shared.h:8:22:8:25 | nptr |
129+
| dispatch.cpp:34:22:34:27 | call to getenv | dispatch.cpp:7:20:7:28 | sinkParam |
130+
| dispatch.cpp:34:22:34:27 | call to getenv | dispatch.cpp:8:8:8:16 | sinkParam |
131+
| dispatch.cpp:34:22:34:27 | call to getenv | dispatch.cpp:34:17:34:20 | call to atoi |
132+
| dispatch.cpp:34:22:34:27 | call to getenv | dispatch.cpp:34:22:34:27 | call to getenv |
133+
| dispatch.cpp:34:22:34:27 | call to getenv | dispatch.cpp:34:22:34:38 | (const char *)... |
134+
| dispatch.cpp:34:22:34:27 | call to getenv | shared.h:6:15:6:23 | sinkparam |
135+
| dispatch.cpp:34:22:34:27 | call to getenv | shared.h:8:22:8:25 | nptr |
101136
| globals.cpp:5:20:5:25 | call to getenv | globals.cpp:5:12:5:16 | local |
102137
| globals.cpp:5:20:5:25 | call to getenv | globals.cpp:5:20:5:25 | call to getenv |
103138
| globals.cpp:5:20:5:25 | call to getenv | globals.cpp:6:10:6:14 | (const char *)... |

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

+6
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@
2020
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:98:10:98:11 | (const char *)... | IR only |
2121
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:98:10:98:11 | p2 | IR only |
2222
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | shared.h:5:23:5:31 | sinkparam | IR only |
23+
| dispatch.cpp:28:29:28:34 | call to getenv | dispatch.cpp:7:20:7:28 | sinkParam | IR only |
24+
| dispatch.cpp:28:29:28:34 | call to getenv | dispatch.cpp:8:8:8:16 | sinkParam | IR only |
25+
| dispatch.cpp:28:29:28:34 | call to getenv | shared.h:6:15:6:23 | sinkparam | IR only |
26+
| dispatch.cpp:29:32:29:37 | call to getenv | dispatch.cpp:7:20:7:28 | sinkParam | IR only |
27+
| dispatch.cpp:29:32:29:37 | call to getenv | dispatch.cpp:8:8:8:16 | sinkParam | IR only |
28+
| dispatch.cpp:29:32:29:37 | call to getenv | shared.h:6:15:6:23 | sinkparam | IR only |
2329
| globals.cpp:13:15:13:20 | call to getenv | globals.cpp:13:5:13:11 | global1 | AST only |
2430
| globals.cpp:23:15:23:20 | call to getenv | globals.cpp:23:5:23:11 | global2 | AST only |
2531
| test_diff.cpp:104:12:104:15 | argv | test_diff.cpp:104:11:104:20 | (...) | IR only |

0 commit comments

Comments
 (0)