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`.
This commit is contained in:
Jonas Jensen
2020-05-18 15:37:22 +02:00
parent cc00f0f584
commit f2402c5abb
3 changed files with 76 additions and 0 deletions

View File

@@ -0,0 +1,35 @@
#include "shared.h"
using SinkFunction = void (*)(int);
void notSink(int notSinkParam);
void callsSink(int sinkParam) {
sink(sinkParam);
}
struct {
SinkFunction sinkPtr, notSinkPtr;
} globalStruct;
union {
SinkFunction sinkPtr, notSinkPtr;
} globalUnion;
SinkFunction globalSinkPtr;
void assignGlobals() {
globalStruct.sinkPtr = callsSink;
globalUnion.sinkPtr = callsSink;
globalSinkPtr = callsSink;
};
void testStruct() {
globalStruct.sinkPtr(atoi(getenv("TAINTED"))); // should reach sinkParam [NOT DETECTED in AST]
globalStruct.notSinkPtr(atoi(getenv("TAINTED"))); // shouldn't reach sinkParam [FALSE POSITIVE in IR]
globalUnion.sinkPtr(atoi(getenv("TAINTED"))); // should reach sinkParam
globalUnion.notSinkPtr(atoi(getenv("TAINTED"))); // should reach sinkParam
globalSinkPtr(atoi(getenv("TAINTED"))); // should reach sinkParam
}

View File

@@ -98,6 +98,41 @@
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:98:10:98:11 | (const char *)... |
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:98:10:98:11 | p2 |
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | shared.h:5:23:5:31 | sinkparam |
| dispatch.cpp:28:29:28:34 | call to getenv | dispatch.cpp:7:20:7:28 | sinkParam |
| dispatch.cpp:28:29:28:34 | call to getenv | dispatch.cpp:8:8:8:16 | sinkParam |
| dispatch.cpp:28:29:28:34 | call to getenv | dispatch.cpp:28:24:28:27 | call to atoi |
| dispatch.cpp:28:29:28:34 | call to getenv | dispatch.cpp:28:29:28:34 | call to getenv |
| dispatch.cpp:28:29:28:34 | call to getenv | dispatch.cpp:28:29:28:45 | (const char *)... |
| dispatch.cpp:28:29:28:34 | call to getenv | shared.h:6:15:6:23 | sinkparam |
| dispatch.cpp:28:29:28:34 | call to getenv | shared.h:8:22:8:25 | nptr |
| dispatch.cpp:29:32:29:37 | call to getenv | dispatch.cpp:7:20:7:28 | sinkParam |
| dispatch.cpp:29:32:29:37 | call to getenv | dispatch.cpp:8:8:8:16 | sinkParam |
| dispatch.cpp:29:32:29:37 | call to getenv | dispatch.cpp:29:27:29:30 | call to atoi |
| dispatch.cpp:29:32:29:37 | call to getenv | dispatch.cpp:29:32:29:37 | call to getenv |
| dispatch.cpp:29:32:29:37 | call to getenv | dispatch.cpp:29:32:29:48 | (const char *)... |
| dispatch.cpp:29:32:29:37 | call to getenv | shared.h:6:15:6:23 | sinkparam |
| dispatch.cpp:29:32:29:37 | call to getenv | shared.h:8:22:8:25 | nptr |
| dispatch.cpp:31:28:31:33 | call to getenv | dispatch.cpp:7:20:7:28 | sinkParam |
| dispatch.cpp:31:28:31:33 | call to getenv | dispatch.cpp:8:8:8:16 | sinkParam |
| dispatch.cpp:31:28:31:33 | call to getenv | dispatch.cpp:31:23:31:26 | call to atoi |
| dispatch.cpp:31:28:31:33 | call to getenv | dispatch.cpp:31:28:31:33 | call to getenv |
| dispatch.cpp:31:28:31:33 | call to getenv | dispatch.cpp:31:28:31:44 | (const char *)... |
| dispatch.cpp:31:28:31:33 | call to getenv | shared.h:6:15:6:23 | sinkparam |
| dispatch.cpp:31:28:31:33 | call to getenv | shared.h:8:22:8:25 | nptr |
| dispatch.cpp:32:31:32:36 | call to getenv | dispatch.cpp:7:20:7:28 | sinkParam |
| dispatch.cpp:32:31:32:36 | call to getenv | dispatch.cpp:8:8:8:16 | sinkParam |
| dispatch.cpp:32:31:32:36 | call to getenv | dispatch.cpp:32:26:32:29 | call to atoi |
| dispatch.cpp:32:31:32:36 | call to getenv | dispatch.cpp:32:31:32:36 | call to getenv |
| dispatch.cpp:32:31:32:36 | call to getenv | dispatch.cpp:32:31:32:47 | (const char *)... |
| dispatch.cpp:32:31:32:36 | call to getenv | shared.h:6:15:6:23 | sinkparam |
| dispatch.cpp:32:31:32:36 | call to getenv | shared.h:8:22:8:25 | nptr |
| dispatch.cpp:34:22:34:27 | call to getenv | dispatch.cpp:7:20:7:28 | sinkParam |
| dispatch.cpp:34:22:34:27 | call to getenv | dispatch.cpp:8:8:8:16 | sinkParam |
| dispatch.cpp:34:22:34:27 | call to getenv | dispatch.cpp:34:17:34:20 | call to atoi |
| dispatch.cpp:34:22:34:27 | call to getenv | dispatch.cpp:34:22:34:27 | call to getenv |
| dispatch.cpp:34:22:34:27 | call to getenv | dispatch.cpp:34:22:34:38 | (const char *)... |
| dispatch.cpp:34:22:34:27 | call to getenv | shared.h:6:15:6:23 | sinkparam |
| dispatch.cpp:34:22:34:27 | call to getenv | shared.h:8:22:8:25 | nptr |
| globals.cpp:5:20:5:25 | call to getenv | globals.cpp:5:12:5:16 | local |
| globals.cpp:5:20:5:25 | call to getenv | globals.cpp:5:20:5:25 | call to getenv |
| globals.cpp:5:20:5:25 | call to getenv | globals.cpp:6:10:6:14 | (const char *)... |

View File

@@ -20,6 +20,12 @@
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:98:10:98:11 | (const char *)... | IR only |
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:98:10:98:11 | p2 | IR only |
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | shared.h:5:23:5:31 | sinkparam | IR only |
| dispatch.cpp:28:29:28:34 | call to getenv | dispatch.cpp:7:20:7:28 | sinkParam | IR only |
| dispatch.cpp:28:29:28:34 | call to getenv | dispatch.cpp:8:8:8:16 | sinkParam | IR only |
| dispatch.cpp:28:29:28:34 | call to getenv | shared.h:6:15:6:23 | sinkparam | IR only |
| dispatch.cpp:29:32:29:37 | call to getenv | dispatch.cpp:7:20:7:28 | sinkParam | IR only |
| dispatch.cpp:29:32:29:37 | call to getenv | dispatch.cpp:8:8:8:16 | sinkParam | IR only |
| dispatch.cpp:29:32:29:37 | call to getenv | shared.h:6:15:6:23 | sinkparam | IR only |
| globals.cpp:13:15:13:20 | call to getenv | globals.cpp:13:5:13:11 | global1 | AST only |
| globals.cpp:23:15:23:20 | call to getenv | globals.cpp:23:5:23:11 | global2 | AST only |
| test_diff.cpp:104:12:104:15 | argv | test_diff.cpp:104:11:104:20 | (...) | IR only |