C++ IR: Support for global virtual dispatch

The IR data flow library now supports virtual dispatch with a library
that's similar to `security.TaintTracking`. In particular, it should
have the same performance characteristics. The main difference is that
non-recursive callers of `flowsFrom` now pass `_` instead of `true` for
`boolean allowFromArg`. This change allows flow through `return` to
actually work.
This commit is contained in:
Jonas Jensen
2020-01-15 13:19:06 +01:00
parent f7278d36e1
commit f4d0c5e905
4 changed files with 190 additions and 46 deletions

View File

@@ -44,3 +44,66 @@ void VirtualDispatch(Bottom *bottomPtr, Bottom &bottomRef) {
sink(topRef.notSource2()); // no flow [FALSE POSITIVE]
topRef.notSink(source()); // no flow [FALSE POSITIVE]
}
Top *globalBottom, *globalMiddle;
Top *readGlobalBottom() {
return globalBottom;
}
void DispatchThroughGlobal() {
sink(globalBottom->isSource1()); // flow [NOT DETECTED by AST]
sink(globalMiddle->isSource1()); // no flow
sink(readGlobalBottom()->isSource1()); // flow [NOT DETECTED by AST]
globalBottom = new Bottom();
globalMiddle = new Middle();
}
Top *allocateBottom() {
return new Bottom();
}
void callSinkByPointer(Top *top) {
top->isSink(source()); // flow [NOT DETECTED by AST]
}
void callSinkByReference(Top &top) {
top.isSink(source()); // flow [NOT DETECTED by AST]
}
void globalVirtualDispatch() {
callSinkByPointer(allocateBottom());
callSinkByReference(*allocateBottom());
Top *x = allocateBottom();
x->isSink(source()); // flow [NOT DETECTED by AST]
}
Top *identity(Top *top) {
return top;
}
void callIdentityFunctions(Top *top, Bottom *bottom) {
identity(bottom)->isSink(source()); // flow [NOT DETECTED]
identity(top)->isSink(source()); // now flow
}
using SinkFunctionType = void (*)(int);
void callSink(int x) {
sink(x);
}
SinkFunctionType returnCallSink() {
return callSink;
}
void testFunctionPointer(SinkFunctionType maybeCallSink, SinkFunctionType dontCallSink, bool b) {
if (b) {
maybeCallSink = returnCallSink();
}
maybeCallSink(source()); // flow [NOT DETECTED by AST]
dontCallSink(source()); // no flow
}

View File

@@ -10,8 +10,14 @@
| dispatch.cpp:16:37:16:42 | dispatch.cpp:40:15:40:23 | IR only |
| dispatch.cpp:22:37:22:42 | dispatch.cpp:31:16:31:24 | IR only |
| dispatch.cpp:22:37:22:42 | dispatch.cpp:39:15:39:23 | IR only |
| dispatch.cpp:22:37:22:42 | dispatch.cpp:55:22:55:30 | IR only |
| dispatch.cpp:22:37:22:42 | dispatch.cpp:58:28:58:36 | IR only |
| dispatch.cpp:33:18:33:23 | dispatch.cpp:23:38:23:38 | IR only |
| dispatch.cpp:41:17:41:22 | dispatch.cpp:23:38:23:38 | IR only |
| dispatch.cpp:69:15:69:20 | dispatch.cpp:23:38:23:38 | IR only |
| dispatch.cpp:73:14:73:19 | dispatch.cpp:23:38:23:38 | IR only |
| dispatch.cpp:81:13:81:18 | dispatch.cpp:23:38:23:38 | IR only |
| dispatch.cpp:107:17:107:22 | dispatch.cpp:96:8:96:8 | IR only |
| lambdas.cpp:8:10:8:15 | lambdas.cpp:14:3:14:6 | AST only |
| lambdas.cpp:8:10:8:15 | lambdas.cpp:18:8:18:8 | AST only |
| lambdas.cpp:8:10:8:15 | lambdas.cpp:21:3:21:6 | AST only |

View File

@@ -14,6 +14,9 @@
| dispatch.cpp:11:38:11:38 | x | dispatch.cpp:45:18:45:23 | call to source |
| dispatch.cpp:23:38:23:38 | x | dispatch.cpp:33:18:33:23 | call to source |
| dispatch.cpp:23:38:23:38 | x | dispatch.cpp:41:17:41:22 | call to source |
| dispatch.cpp:23:38:23:38 | x | dispatch.cpp:69:15:69:20 | call to source |
| dispatch.cpp:23:38:23:38 | x | dispatch.cpp:73:14:73:19 | call to source |
| dispatch.cpp:23:38:23:38 | x | dispatch.cpp:81:13:81:18 | call to source |
| dispatch.cpp:31:16:31:24 | call to isSource1 | dispatch.cpp:22:37:22:42 | call to source |
| dispatch.cpp:32:16:32:24 | call to isSource2 | dispatch.cpp:16:37:16:42 | call to source |
| dispatch.cpp:35:16:35:25 | call to notSource1 | dispatch.cpp:9:37:9:42 | call to source |
@@ -22,6 +25,9 @@
| dispatch.cpp:40:15:40:23 | call to isSource2 | dispatch.cpp:16:37:16:42 | call to source |
| dispatch.cpp:43:15:43:24 | call to notSource1 | dispatch.cpp:9:37:9:42 | call to source |
| dispatch.cpp:44:15:44:24 | call to notSource2 | dispatch.cpp:10:37:10:42 | call to source |
| dispatch.cpp:55:22:55:30 | call to isSource1 | dispatch.cpp:22:37:22:42 | call to source |
| dispatch.cpp:58:28:58:36 | call to isSource1 | dispatch.cpp:22:37:22:42 | call to source |
| dispatch.cpp:96:8:96:8 | x | dispatch.cpp:107:17:107:22 | call to source |
| test.cpp:7:8:7:9 | t1 | test.cpp:6:12:6:17 | call to source |
| test.cpp:9:8:9:9 | t1 | test.cpp:6:12:6:17 | call to source |
| test.cpp:10:8:10:9 | t2 | test.cpp:6:12:6:17 | call to source |