mirror of
https://github.com/github/codeql.git
synced 2026-05-02 20:25:13 +02:00
Merge branch 'master' into rdmarsh/cpp/ir-callee-side-effects
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
int source();
|
||||
void sink(int);
|
||||
bool guarded(int);
|
||||
|
||||
void bg_basic(int source) {
|
||||
if (guarded(source)) {
|
||||
sink(source); // no flow
|
||||
} else {
|
||||
sink(source); // flow
|
||||
}
|
||||
}
|
||||
|
||||
void bg_not(int source) {
|
||||
if (!guarded(source)) {
|
||||
sink(source); // flow
|
||||
} else {
|
||||
sink(source); // no flow
|
||||
}
|
||||
}
|
||||
|
||||
void bg_and(int source, bool arbitrary) {
|
||||
if (guarded(source) && arbitrary) {
|
||||
sink(source); // no flow
|
||||
} else {
|
||||
sink(source); // flow
|
||||
}
|
||||
}
|
||||
|
||||
void bg_or(int source, bool arbitrary) {
|
||||
if (guarded(source) || arbitrary) {
|
||||
sink(source); // flow
|
||||
} else {
|
||||
sink(source); // flow
|
||||
}
|
||||
}
|
||||
|
||||
void bg_return(int source) {
|
||||
if (!guarded(source)) {
|
||||
return;
|
||||
}
|
||||
sink(source); // no flow
|
||||
}
|
||||
|
||||
struct XY {
|
||||
int x, y;
|
||||
};
|
||||
|
||||
void bg_stackstruct(XY s1, XY s2) {
|
||||
s1.x = source();
|
||||
if (guarded(s1.x)) {
|
||||
sink(s1.x); // no flow
|
||||
} else if (guarded(s1.y)) {
|
||||
sink(s1.x); // flow
|
||||
} else if (guarded(s2.y)) {
|
||||
sink(s1.x); // flow
|
||||
}
|
||||
}
|
||||
|
||||
void bg_structptr(XY *p1, XY *p2) {
|
||||
p1->x = source();
|
||||
if (guarded(p1->x)) {
|
||||
sink(p1->x); // no flow [FALSE POSITIVE in AST]
|
||||
} else if (guarded(p1->y)) {
|
||||
sink(p1->x); // flow [NOT DETECTED in IR]
|
||||
} else if (guarded(p2->x)) {
|
||||
sink(p1->x); // flow [NOT DETECTED in IR]
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,20 @@
|
||||
import cpp
|
||||
import semmle.code.cpp.dataflow.DataFlow
|
||||
|
||||
/**
|
||||
* A `BarrierGuard` that stops flow to all occurrences of `x` within statement
|
||||
* S in `if (guarded(x)) S`.
|
||||
*/
|
||||
// This is tested in `BarrierGuard.cpp`.
|
||||
class TestBarrierGuard extends DataFlow::BarrierGuard {
|
||||
TestBarrierGuard() { this.(FunctionCall).getTarget().getName() = "guarded" }
|
||||
|
||||
override predicate checks(Expr checked, boolean isTrue) {
|
||||
checked = this.(FunctionCall).getArgument(0) and
|
||||
isTrue = true
|
||||
}
|
||||
}
|
||||
|
||||
/** Common data flow configuration to be used by tests. */
|
||||
class TestAllocationConfig extends DataFlow::Configuration {
|
||||
TestAllocationConfig() { this = "TestAllocationConfig" }
|
||||
@@ -26,4 +40,6 @@ class TestAllocationConfig extends DataFlow::Configuration {
|
||||
override predicate isBarrier(DataFlow::Node barrier) {
|
||||
barrier.asExpr().(VariableAccess).getTarget().hasName("barrier")
|
||||
}
|
||||
|
||||
override predicate isBarrierGuard(DataFlow::BarrierGuard bg) { bg instanceof TestBarrierGuard }
|
||||
}
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.dataflow.DataFlow
|
||||
import semmle.code.cpp.ir.IR
|
||||
|
||||
/**
|
||||
* A `BarrierGuard` that stops flow to all occurrences of `x` within statement
|
||||
* S in `if (guarded(x)) S`.
|
||||
*/
|
||||
// This is tested in `BarrierGuard.cpp`.
|
||||
class TestBarrierGuard extends DataFlow::BarrierGuard {
|
||||
TestBarrierGuard() { this.(CallInstruction).getStaticCallTarget().getName() = "guarded" }
|
||||
|
||||
override predicate checks(Instruction checked, boolean isTrue) {
|
||||
checked = this.(CallInstruction).getPositionalArgument(0) and
|
||||
isTrue = true
|
||||
}
|
||||
}
|
||||
|
||||
/** Common data flow configuration to be used by tests. */
|
||||
class TestAllocationConfig extends DataFlow::Configuration {
|
||||
@@ -24,4 +39,6 @@ class TestAllocationConfig extends DataFlow::Configuration {
|
||||
override predicate isBarrier(DataFlow::Node barrier) {
|
||||
barrier.asExpr().(VariableAccess).getTarget().hasName("barrier")
|
||||
}
|
||||
|
||||
override predicate isBarrierGuard(DataFlow::BarrierGuard bg) { bg instanceof TestBarrierGuard }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
int source();
|
||||
void sink(int);
|
||||
|
||||
// This class has the opposite behavior of what the member function names suggest.
|
||||
struct Top {
|
||||
virtual int isSource1() { return 0; }
|
||||
virtual int isSource2() { return 0; }
|
||||
virtual void isSink(int x) { }
|
||||
virtual int notSource1() { return source(); }
|
||||
virtual int notSource2() { return source(); }
|
||||
virtual void notSink(int x) { sink(x); }
|
||||
};
|
||||
|
||||
// This class has the correct behavior for just the functions ending in 2.
|
||||
struct Middle : Top {
|
||||
int isSource2() override { return source(); }
|
||||
int notSource2() override { return 0; }
|
||||
};
|
||||
|
||||
// This class has all the behavior suggested by the function names.
|
||||
struct Bottom : Middle {
|
||||
int isSource1() override { return source(); }
|
||||
void isSink(int x) override { sink(x); }
|
||||
int notSource1() override { return 0; }
|
||||
void notSink(int x) override { }
|
||||
};
|
||||
|
||||
void VirtualDispatch(Bottom *bottomPtr, Bottom &bottomRef) {
|
||||
Top *topPtr = bottomPtr, &topRef = bottomRef;
|
||||
|
||||
sink(topPtr->isSource1()); // flow [NOT DETECTED by AST]
|
||||
sink(topPtr->isSource2()); // flow [NOT DETECTED by AST]
|
||||
topPtr->isSink(source()); // flow [NOT DETECTED by AST]
|
||||
|
||||
sink(topPtr->notSource1()); // no flow [FALSE POSITIVE]
|
||||
sink(topPtr->notSource2()); // no flow [FALSE POSITIVE]
|
||||
topPtr->notSink(source()); // no flow [FALSE POSITIVE]
|
||||
|
||||
sink(topRef.isSource1()); // flow [NOT DETECTED by AST]
|
||||
sink(topRef.isSource2()); // flow [NOT DETECTED by AST]
|
||||
topRef.isSink(source()); // flow [NOT DETECTED by AST]
|
||||
|
||||
sink(topRef.notSource1()); // no flow [FALSE POSITIVE]
|
||||
sink(topRef.notSource2()); // no flow [FALSE POSITIVE]
|
||||
topRef.notSink(source()); // no flow [FALSE POSITIVE]
|
||||
}
|
||||
@@ -1,3 +1,13 @@
|
||||
| BarrierGuard.cpp:9:10:9:15 | source | BarrierGuard.cpp:5:19:5:24 | source |
|
||||
| BarrierGuard.cpp:15:10:15:15 | source | BarrierGuard.cpp:13:17:13:22 | source |
|
||||
| BarrierGuard.cpp:25:10:25:15 | source | BarrierGuard.cpp:21:17:21:22 | source |
|
||||
| BarrierGuard.cpp:31:10:31:15 | source | BarrierGuard.cpp:29:16:29:21 | source |
|
||||
| BarrierGuard.cpp:33:10:33:15 | source | BarrierGuard.cpp:29:16:29:21 | source |
|
||||
| BarrierGuard.cpp:53:13:53:13 | x | BarrierGuard.cpp:49:10:49:15 | call to source |
|
||||
| BarrierGuard.cpp:55:13:55:13 | x | BarrierGuard.cpp:49:10:49:15 | call to source |
|
||||
| BarrierGuard.cpp:62:14:62:14 | x | BarrierGuard.cpp:60:11:60:16 | call to source |
|
||||
| BarrierGuard.cpp:64:14:64:14 | x | BarrierGuard.cpp:60:11:60:16 | call to source |
|
||||
| BarrierGuard.cpp:66:14:66:14 | x | BarrierGuard.cpp:60:11:60:16 | call to source |
|
||||
| acrossLinkTargets.cpp:12:8:12:8 | x | acrossLinkTargets.cpp:19:27:19:32 | call to source |
|
||||
| clang.cpp:18:8:18:19 | sourceArray1 | clang.cpp:12:9:12:20 | sourceArray1 |
|
||||
| clang.cpp:22:8:22:20 | & ... | clang.cpp:12:9:12:20 | sourceArray1 |
|
||||
@@ -5,6 +15,12 @@
|
||||
| clang.cpp:30:27:30:34 | call to getFirst | clang.cpp:28:27:28:32 | call to source |
|
||||
| clang.cpp:37:10:37:11 | m2 | clang.cpp:34:32:34:37 | call to source |
|
||||
| clang.cpp:45:17:45:18 | m2 | clang.cpp:43:35:43:40 | call to source |
|
||||
| dispatch.cpp:11:38:11:38 | x | dispatch.cpp:37:19:37:24 | call to source |
|
||||
| dispatch.cpp:11:38:11:38 | x | dispatch.cpp:45:18:45:23 | call to source |
|
||||
| dispatch.cpp:35:16:35:25 | call to notSource1 | dispatch.cpp:9:37:9:42 | call to source |
|
||||
| dispatch.cpp:36:16:36:25 | call to notSource2 | dispatch.cpp:10:37:10: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 |
|
||||
| lambdas.cpp:14:3:14:6 | t | lambdas.cpp:8:10:8:15 | call to source |
|
||||
| lambdas.cpp:18:8:18:8 | call to operator() | lambdas.cpp:8:10:8:15 | call to source |
|
||||
| lambdas.cpp:21:3:21:6 | t | lambdas.cpp:8:10:8:15 | call to source |
|
||||
|
||||
@@ -1,8 +1,17 @@
|
||||
| BarrierGuard.cpp:60:11:60:16 | BarrierGuard.cpp:62:14:62:14 | AST only |
|
||||
| BarrierGuard.cpp:60:11:60:16 | BarrierGuard.cpp:64:14:64:14 | AST only |
|
||||
| BarrierGuard.cpp:60:11:60:16 | BarrierGuard.cpp:66:14:66:14 | AST only |
|
||||
| clang.cpp:12:9:12:20 | clang.cpp:18:8:18:19 | AST only |
|
||||
| clang.cpp:12:9:12:20 | clang.cpp:22:8:22:20 | AST only |
|
||||
| clang.cpp:28:27:28:32 | clang.cpp:29:27:29:28 | AST only |
|
||||
| clang.cpp:28:27:28:32 | clang.cpp:30:27:30:34 | AST only |
|
||||
| clang.cpp:39:42:39:47 | clang.cpp:41:18:41:19 | IR only |
|
||||
| dispatch.cpp:16:37:16:42 | dispatch.cpp:32:16:32:24 | IR only |
|
||||
| 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: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 |
|
||||
| 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 |
|
||||
|
||||
@@ -1,8 +1,27 @@
|
||||
| BarrierGuard.cpp:9:10:9:15 | Load: source | BarrierGuard.cpp:5:19:5:24 | InitializeParameter: source |
|
||||
| BarrierGuard.cpp:15:10:15:15 | Load: source | BarrierGuard.cpp:13:17:13:22 | InitializeParameter: source |
|
||||
| BarrierGuard.cpp:25:10:25:15 | Load: source | BarrierGuard.cpp:21:17:21:22 | InitializeParameter: source |
|
||||
| BarrierGuard.cpp:31:10:31:15 | Load: source | BarrierGuard.cpp:29:16:29:21 | InitializeParameter: source |
|
||||
| BarrierGuard.cpp:33:10:33:15 | Load: source | BarrierGuard.cpp:29:16:29:21 | InitializeParameter: source |
|
||||
| BarrierGuard.cpp:53:13:53:13 | Load: x | BarrierGuard.cpp:49:10:49:15 | Call: call to source |
|
||||
| BarrierGuard.cpp:55:13:55:13 | Load: x | BarrierGuard.cpp:49:10:49:15 | Call: call to source |
|
||||
| acrossLinkTargets.cpp:12:8:12:8 | Convert: (int)... | acrossLinkTargets.cpp:19:27:19:32 | Call: call to source |
|
||||
| acrossLinkTargets.cpp:12:8:12:8 | Load: x | acrossLinkTargets.cpp:19:27:19:32 | Call: call to source |
|
||||
| clang.cpp:37:10:37:11 | Load: m2 | clang.cpp:34:32:34:37 | Call: call to source |
|
||||
| clang.cpp:41:18:41:19 | Load: m2 | clang.cpp:39:42:39:47 | Call: call to source |
|
||||
| clang.cpp:45:17:45:18 | Load: m2 | clang.cpp:43:35:43:40 | Call: call to source |
|
||||
| dispatch.cpp:11:38:11:38 | Load: x | dispatch.cpp:37:19:37:24 | Call: call to source |
|
||||
| dispatch.cpp:11:38:11:38 | Load: x | dispatch.cpp:45:18:45:23 | Call: call to source |
|
||||
| dispatch.cpp:23:38:23:38 | Load: x | dispatch.cpp:33:18:33:23 | Call: call to source |
|
||||
| dispatch.cpp:23:38:23:38 | Load: x | dispatch.cpp:41:17:41:22 | Call: call to source |
|
||||
| dispatch.cpp:31:16:31:24 | Call: call to isSource1 | dispatch.cpp:22:37:22:42 | Call: call to source |
|
||||
| dispatch.cpp:32:16:32:24 | Call: call to isSource2 | dispatch.cpp:16:37:16:42 | Call: call to source |
|
||||
| dispatch.cpp:35:16:35:25 | Call: call to notSource1 | dispatch.cpp:9:37:9:42 | Call: call to source |
|
||||
| dispatch.cpp:36:16:36:25 | Call: call to notSource2 | dispatch.cpp:10:37:10:42 | Call: call to source |
|
||||
| dispatch.cpp:39:15:39:23 | Call: call to isSource1 | dispatch.cpp:22:37:22:42 | Call: call to source |
|
||||
| dispatch.cpp:40:15:40:23 | Call: call to isSource2 | dispatch.cpp:16:37:16:42 | Call: call to source |
|
||||
| dispatch.cpp:43:15:43:24 | Call: call to notSource1 | dispatch.cpp:9:37:9:42 | Call: call to source |
|
||||
| dispatch.cpp:44:15:44:24 | Call: call to notSource2 | dispatch.cpp:10:37:10:42 | Call: call to source |
|
||||
| test.cpp:7:8:7:9 | Load: t1 | test.cpp:6:12:6:17 | Call: call to source |
|
||||
| test.cpp:9:8:9:9 | Load: t1 | test.cpp:6:12:6:17 | Call: call to source |
|
||||
| test.cpp:10:8:10:9 | Load: t2 | test.cpp:6:12:6:17 | Call: call to source |
|
||||
|
||||
Reference in New Issue
Block a user