mirror of
https://github.com/github/codeql.git
synced 2026-05-02 12:15:17 +02:00
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:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
Reference in New Issue
Block a user