diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/global.expected b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/global.expected new file mode 100644 index 00000000000..520ebcbff1f --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/global.expected @@ -0,0 +1,4 @@ +| globals.cpp:13:15:13:20 | call to getenv | globals.cpp:2:17:2:25 | sinkParam | global1 | +| globals.cpp:13:15:13:20 | call to getenv | globals.cpp:12:10:12:16 | global1 | global1 | +| globals.cpp:23:15:23:20 | call to getenv | globals.cpp:2:17:2:25 | sinkParam | global2 | +| globals.cpp:23:15:23:20 | call to getenv | globals.cpp:19:10:19:16 | global2 | global2 | diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/global.ql b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/global.ql new file mode 100644 index 00000000000..6f853c6480c --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/global.ql @@ -0,0 +1,7 @@ +import semmle.code.cpp.ir.dataflow.DefaultTaintTracking + +from Expr source, Element tainted, string globalVar +where + taintedIncludingGlobalVars(source, tainted, globalVar) and + globalVar != "" +select source, tainted, globalVar diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/globals.cpp b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/globals.cpp new file mode 100644 index 00000000000..54e0718ceef --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/globals.cpp @@ -0,0 +1,24 @@ +char * getenv(const char *); +void sink(char *sinkParam); + +void throughLocal() { + char * local = getenv("VAR"); + sink(local); // flow +} + +char * global1 = 0; + +void readWriteGlobal1() { + sink(global1); // flow + global1 = getenv("VAR"); +} + +static char * global2 = 0; + +void readGlobal2() { + sink(global2); // flow +} + +void writeGlobal2() { + global2 = getenv("VAR"); +} diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/tainted.expected b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/tainted.expected index d8ef6c68258..99e970c9b40 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/tainted.expected +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/tainted.expected @@ -101,6 +101,14 @@ | defaulttainttracking.cpp:88:18:88:23 | call to getenv | defaulttainttracking.cpp:88:18:88:23 | call to getenv | | defaulttainttracking.cpp:88:18:88:23 | call to getenv | defaulttainttracking.cpp:88:18:88:30 | (reference to) | | defaulttainttracking.cpp:88:18:88:23 | call to getenv | test_diff.cpp:1:11:1:20 | p#0 | +| globals.cpp:5:20:5:25 | call to getenv | globals.cpp:2:17:2:25 | sinkParam | +| 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 | local | +| globals.cpp:13:15:13:20 | call to getenv | globals.cpp:9:8:9:14 | global1 | +| globals.cpp:13:15:13:20 | call to getenv | globals.cpp:13:15:13:20 | call to getenv | +| globals.cpp:23:15:23:20 | call to getenv | globals.cpp:16:15:16:21 | global2 | +| globals.cpp:23:15:23:20 | call to getenv | globals.cpp:23:15:23:20 | call to getenv | | test_diff.cpp:92:10:92:13 | argv | defaulttainttracking.cpp:9:11:9:20 | p#0 | | test_diff.cpp:92:10:92:13 | argv | test_diff.cpp:1:11:1:20 | p#0 | | test_diff.cpp:92:10:92:13 | argv | test_diff.cpp:92:10:92:13 | argv | diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/test_diff.expected b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/test_diff.expected index 2b464f27607..335cca91c33 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/test_diff.expected +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/test_diff.expected @@ -15,6 +15,8 @@ | defaulttainttracking.cpp:88:18:88:23 | call to getenv | defaulttainttracking.cpp:88:8:88:32 | (reference dereference) | IR only | | defaulttainttracking.cpp:88:18:88:23 | call to getenv | defaulttainttracking.cpp:88:18:88:30 | (reference to) | IR only | | defaulttainttracking.cpp:88:18:88:23 | call to getenv | test_diff.cpp:1:11:1:20 | p#0 | 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 | | test_diff.cpp:108:10:108:13 | argv | test_diff.cpp:36:24:36:24 | p | AST only | | test_diff.cpp:111:10:111:13 | argv | defaulttainttracking.cpp:9:11:9:20 | p#0 | AST only | diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/IRDataflowTestCommon.qll b/cpp/ql/test/library-tests/dataflow/dataflow-tests/IRDataflowTestCommon.qll index 490f7e4290a..58a1dd2672b 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/IRDataflowTestCommon.qll +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/IRDataflowTestCommon.qll @@ -36,9 +36,27 @@ class TestAllocationConfig extends DataFlow::Configuration { ) } + override predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) { + exists(GlobalOrNamespaceVariable var | var.getName().matches("flowTestGlobal%") | + writesVariable(n1.asInstruction(), var) and + var = n2.asVariable() + or + readsVariable(n2.asInstruction(), var) and + var = n1.asVariable() + ) + } + override predicate isBarrier(DataFlow::Node barrier) { barrier.asExpr().(VariableAccess).getTarget().hasName("barrier") } override predicate isBarrierGuard(DataFlow::BarrierGuard bg) { bg instanceof TestBarrierGuard } } + +private predicate readsVariable(LoadInstruction load, Variable var) { + load.getSourceAddress().(VariableAddressInstruction).getASTVariable() = var +} + +private predicate writesVariable(StoreInstruction store, Variable var) { + store.getDestinationAddress().(VariableAddressInstruction).getASTVariable() = var +} diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/globals.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/globals.cpp new file mode 100644 index 00000000000..c019fa6198b --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/globals.cpp @@ -0,0 +1,24 @@ +int source(); +void sink(int); + +void throughLocal() { + int local = source(); + sink(local); // flow +} + +int flowTestGlobal1 = 0; + +void readWriteGlobal1() { + sink(flowTestGlobal1); // flow + flowTestGlobal1 = source(); +} + +static int flowTestGlobal2 = 0; + +void readGlobal2() { + sink(flowTestGlobal2); // flow +} + +void writeGlobal2() { + flowTestGlobal2 = source(); +} diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected index 04ad48cd4d6..6ff83eb74b5 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected @@ -22,6 +22,7 @@ | 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 | +| globals.cpp:6:10:6:14 | local | globals.cpp:5:17:5:22 | 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 | diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_diff.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_diff.expected index 8daa9b4b39b..71630f892f5 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_diff.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_diff.expected @@ -17,6 +17,8 @@ | dispatch.cpp:107:17:107:22 | dispatch.cpp:96:8:96:8 | IR only | | dispatch.cpp:140:8:140:13 | dispatch.cpp:96:8:96:8 | IR only | | dispatch.cpp:144:8:144:13 | dispatch.cpp:96:8:96:8 | IR only | +| globals.cpp:13:23:13:28 | globals.cpp:12:10:12:24 | IR only | +| globals.cpp:23:23:23:28 | globals.cpp:19:10:19:24 | 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 | diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_ir.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_ir.expected index bb20ccfc9d7..275cbabc075 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_ir.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_ir.expected @@ -35,6 +35,9 @@ | dispatch.cpp:96:8:96:8 | x | dispatch.cpp:107:17:107:22 | call to source | | dispatch.cpp:96:8:96:8 | x | dispatch.cpp:140:8:140:13 | call to source | | dispatch.cpp:96:8:96:8 | x | dispatch.cpp:144:8:144:13 | call to source | +| globals.cpp:6:10:6:14 | local | globals.cpp:5:17:5:22 | call to source | +| globals.cpp:12:10:12:24 | flowTestGlobal1 | globals.cpp:13:23:13:28 | call to source | +| globals.cpp:19:10:19:24 | flowTestGlobal2 | globals.cpp:23:23:23:28 | call to source | | lambdas.cpp:35:8:35:8 | a | lambdas.cpp:8:10:8:15 | 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 |