From 02e1edd6403de32f84c34288287a731816ceeaee Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 13 Aug 2019 18:07:21 +0100 Subject: [PATCH 1/3] CPP: Test taint through lambdas. --- .../dataflow/taint-tests/localTaint.expected | 54 +++++++++++++++++++ .../dataflow/taint-tests/taint.cpp | 45 ++++++++++++++++ .../dataflow/taint-tests/taint.expected | 2 + .../dataflow/taint-tests/test_diff.expected | 2 + 4 files changed, 103 insertions(+) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index 875e5619c840..58fb4b12ecef 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -1,7 +1,20 @@ +| file://:0:0:0:0 | t | taint.cpp:235:11:239:2 | {...} | TAINT | +| file://:0:0:0:0 | t | taint.cpp:243:11:246:2 | {...} | TAINT | +| file://:0:0:0:0 | this | file://:0:0:0:0 | t | TAINT | +| file://:0:0:0:0 | this | file://:0:0:0:0 | t | TAINT | +| file://:0:0:0:0 | this | file://:0:0:0:0 | t | TAINT | +| file://:0:0:0:0 | this | file://:0:0:0:0 | t | TAINT | | file://:0:0:0:0 | this | file://:0:0:0:0 | this | | +| file://:0:0:0:0 | this | file://:0:0:0:0 | u | TAINT | +| file://:0:0:0:0 | this | file://:0:0:0:0 | u | TAINT | +| file://:0:0:0:0 | this | file://:0:0:0:0 | u | TAINT | +| file://:0:0:0:0 | this | file://:0:0:0:0 | v | TAINT | | file://:0:0:0:0 | this | taint.cpp:72:3:72:3 | c | TAINT | | file://:0:0:0:0 | this | taint.cpp:73:3:73:3 | d | TAINT | | file://:0:0:0:0 | this | taint.cpp:77:3:77:3 | d | TAINT | +| file://:0:0:0:0 | u | taint.cpp:235:11:239:2 | {...} | TAINT | +| file://:0:0:0:0 | u | taint.cpp:243:11:246:2 | {...} | TAINT | +| file://:0:0:0:0 | v | taint.cpp:235:11:239:2 | {...} | TAINT | | taint.cpp:4:27:4:33 | source1 | taint.cpp:6:13:6:19 | source1 | | | taint.cpp:4:40:4:45 | clean1 | taint.cpp:5:8:5:13 | clean1 | | | taint.cpp:4:40:4:45 | clean1 | taint.cpp:6:3:6:8 | clean1 | | @@ -178,3 +191,44 @@ | taint.cpp:213:12:213:12 | x | taint.cpp:213:15:213:15 | ref arg y | | | taint.cpp:213:15:213:15 | ref arg y | taint.cpp:216:7:216:7 | y | | | taint.cpp:213:15:213:15 | y | taint.cpp:213:12:213:12 | ref arg x | | +| taint.cpp:223:10:223:15 | call to source | file://:0:0:0:0 | t | | +| taint.cpp:223:10:223:15 | call to source | file://:0:0:0:0 | t | | +| taint.cpp:223:10:223:15 | call to source | taint.cpp:228:12:228:12 | t | | +| taint.cpp:223:10:223:15 | call to source | taint.cpp:253:4:253:4 | t | | +| taint.cpp:223:10:223:15 | call to source | taint.cpp:260:4:260:4 | t | | +| taint.cpp:224:9:224:10 | 0 | file://:0:0:0:0 | u | | +| taint.cpp:224:9:224:10 | 0 | file://:0:0:0:0 | u | | +| taint.cpp:224:9:224:10 | 0 | taint.cpp:228:15:228:15 | u | | +| taint.cpp:224:9:224:10 | 0 | taint.cpp:253:7:253:7 | u | | +| taint.cpp:224:9:224:10 | 0 | taint.cpp:260:7:260:7 | u | | +| taint.cpp:225:9:225:10 | 0 | file://:0:0:0:0 | v | | +| taint.cpp:225:9:225:10 | 0 | taint.cpp:241:7:241:7 | v | | +| taint.cpp:226:9:226:10 | 0 | taint.cpp:260:10:260:10 | w | | +| taint.cpp:226:9:226:10 | 0 | taint.cpp:261:7:261:7 | w | | +| taint.cpp:228:11:228:11 | Unknown literal | taint.cpp:228:11:228:11 | constructor init of field t | TAINT | +| taint.cpp:228:11:228:11 | Unknown literal | taint.cpp:228:11:228:11 | constructor init of field u | TAINT | +| taint.cpp:228:11:232:2 | [...](...){...} | taint.cpp:233:7:233:7 | a | | +| taint.cpp:228:11:232:2 | {...} | taint.cpp:228:11:232:2 | [...](...){...} | TAINT | +| taint.cpp:228:12:228:12 | t | taint.cpp:228:11:232:2 | {...} | TAINT | +| taint.cpp:228:15:228:15 | u | taint.cpp:228:11:232:2 | {...} | TAINT | +| taint.cpp:235:11:235:11 | Unknown literal | taint.cpp:235:11:235:11 | constructor init of field t | TAINT | +| taint.cpp:235:11:235:11 | Unknown literal | taint.cpp:235:11:235:11 | constructor init of field u | TAINT | +| taint.cpp:235:11:235:11 | Unknown literal | taint.cpp:235:11:235:11 | constructor init of field v | TAINT | +| taint.cpp:235:11:239:2 | [...](...){...} | taint.cpp:240:2:240:2 | b | | +| taint.cpp:235:11:239:2 | {...} | taint.cpp:235:11:239:2 | [...](...){...} | TAINT | +| taint.cpp:238:7:238:12 | call to source | taint.cpp:238:3:238:14 | ... = ... | | +| taint.cpp:243:11:243:11 | Unknown literal | taint.cpp:243:11:243:11 | constructor init of field t | TAINT | +| taint.cpp:243:11:243:11 | Unknown literal | taint.cpp:243:11:243:11 | constructor init of field u | TAINT | +| taint.cpp:243:11:246:2 | [...](...){...} | taint.cpp:247:2:247:2 | c | | +| taint.cpp:243:11:246:2 | {...} | taint.cpp:243:11:246:2 | [...](...){...} | TAINT | +| taint.cpp:249:11:252:2 | [...](...){...} | taint.cpp:253:2:253:2 | d | | +| taint.cpp:249:18:249:18 | a | taint.cpp:250:8:250:8 | a | | +| taint.cpp:249:25:249:25 | b | taint.cpp:251:8:251:8 | b | | +| taint.cpp:255:11:259:2 | [...](...){...} | taint.cpp:260:2:260:2 | e | | +| taint.cpp:255:19:255:19 | a | taint.cpp:256:8:256:8 | a | | +| taint.cpp:255:27:255:27 | b | taint.cpp:257:8:257:8 | b | | +| taint.cpp:258:7:258:12 | call to source | taint.cpp:258:3:258:14 | ... = ... | | +| taint.cpp:260:4:260:4 | ref arg t | taint.cpp:260:4:260:4 | t | | +| taint.cpp:260:7:260:7 | ref arg u | taint.cpp:260:7:260:7 | u | | +| taint.cpp:260:10:260:10 | ref arg w | taint.cpp:260:10:260:10 | w | | +| taint.cpp:260:10:260:10 | ref arg w | taint.cpp:261:7:261:7 | w | | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp index 9cca2dffa918..7be8038fe9f0 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp @@ -215,3 +215,48 @@ void test_swap() { sink(x); // [FALSE POSITIVE] sink(y); // tainted } + +// --- lambdas --- + +void test_lambdas() +{ + int t = source(); + int u = 0; + int v = 0; + int w = 0; + + auto a = [t, u]() -> int { + sink(t); // tainted [NOT DETECTED] + sink(u); + return t; + }; + sink(a()); // tainted [NOT DETECTED] + + auto b = [&] { + sink(t); // tainted [NOT DETECTED] + sink(u); + v = source(); // (v is reference captured) + }; + b(); + sink(v); // tainted [NOT DETECTED] + + auto c = [=] { + sink(t); // tainted [NOT DETECTED] + sink(u); + }; + c(); + + auto d = [](int a, int b) { + sink(a); // tainted + sink(b); + }; + d(t, u); + + auto e = [](int &a, int &b, int &c) { + sink(a); // tainted + sink(b); + c = source(); + }; + e(t, u, w); + sink(w); // tainted [NOT DETECTED] +} diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected index c27bc148c760..1810662ecf3d 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected @@ -20,3 +20,5 @@ | taint.cpp:210:7:210:7 | x | taint.cpp:207:6:207:11 | call to source | | taint.cpp:215:7:215:7 | x | taint.cpp:207:6:207:11 | call to source | | taint.cpp:216:7:216:7 | y | taint.cpp:207:6:207:11 | call to source | +| taint.cpp:250:8:250:8 | a | taint.cpp:223:10:223:15 | call to source | +| taint.cpp:256:8:256:8 | a | taint.cpp:223:10:223:15 | call to source | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected index d86b5b43ef05..dec5d64f5074 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected @@ -12,3 +12,5 @@ | taint.cpp:195:7:195:7 | taint.cpp:193:6:193:6 | AST only | | taint.cpp:215:7:215:7 | taint.cpp:207:6:207:11 | AST only | | taint.cpp:216:7:216:7 | taint.cpp:207:6:207:11 | AST only | +| taint.cpp:250:8:250:8 | taint.cpp:223:10:223:15 | AST only | +| taint.cpp:256:8:256:8 | taint.cpp:223:10:223:15 | AST only | From 1bd4aeebadab8df5dbe0d5908d1518482b7203fe Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 15 Aug 2019 13:59:44 +0100 Subject: [PATCH 2/3] CPP: Effects of #1715. --- .../dataflow/taint-tests/localTaint.expected | 13 ++++++++++--- .../library-tests/dataflow/taint-tests/taint.cpp | 2 +- .../dataflow/taint-tests/taint.expected | 7 +++++++ .../dataflow/taint-tests/test_diff.expected | 2 ++ 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index 58fb4b12ecef..373eae70e688 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -5,6 +5,11 @@ | file://:0:0:0:0 | this | file://:0:0:0:0 | t | TAINT | | file://:0:0:0:0 | this | file://:0:0:0:0 | t | TAINT | | file://:0:0:0:0 | this | file://:0:0:0:0 | this | | +| file://:0:0:0:0 | this | file://:0:0:0:0 | this | | +| file://:0:0:0:0 | this | file://:0:0:0:0 | this | | +| file://:0:0:0:0 | this | file://:0:0:0:0 | this | | +| file://:0:0:0:0 | this | file://:0:0:0:0 | this | | +| file://:0:0:0:0 | this | file://:0:0:0:0 | this | | | file://:0:0:0:0 | this | file://:0:0:0:0 | u | TAINT | | file://:0:0:0:0 | this | file://:0:0:0:0 | u | TAINT | | file://:0:0:0:0 | this | file://:0:0:0:0 | u | TAINT | @@ -211,16 +216,21 @@ | taint.cpp:228:11:232:2 | {...} | taint.cpp:228:11:232:2 | [...](...){...} | TAINT | | taint.cpp:228:12:228:12 | t | taint.cpp:228:11:232:2 | {...} | TAINT | | taint.cpp:228:15:228:15 | u | taint.cpp:228:11:232:2 | {...} | TAINT | +| taint.cpp:228:17:228:17 | `this` parameter in operator() | file://:0:0:0:0 | this | | +| taint.cpp:228:17:228:17 | `this` parameter in operator() | file://:0:0:0:0 | this | | | taint.cpp:235:11:235:11 | Unknown literal | taint.cpp:235:11:235:11 | constructor init of field t | TAINT | | taint.cpp:235:11:235:11 | Unknown literal | taint.cpp:235:11:235:11 | constructor init of field u | TAINT | | taint.cpp:235:11:235:11 | Unknown literal | taint.cpp:235:11:235:11 | constructor init of field v | TAINT | | taint.cpp:235:11:239:2 | [...](...){...} | taint.cpp:240:2:240:2 | b | | | taint.cpp:235:11:239:2 | {...} | taint.cpp:235:11:239:2 | [...](...){...} | TAINT | +| taint.cpp:235:15:235:15 | `this` parameter in operator() | file://:0:0:0:0 | this | | | taint.cpp:238:7:238:12 | call to source | taint.cpp:238:3:238:14 | ... = ... | | | taint.cpp:243:11:243:11 | Unknown literal | taint.cpp:243:11:243:11 | constructor init of field t | TAINT | | taint.cpp:243:11:243:11 | Unknown literal | taint.cpp:243:11:243:11 | constructor init of field u | TAINT | | taint.cpp:243:11:246:2 | [...](...){...} | taint.cpp:247:2:247:2 | c | | | taint.cpp:243:11:246:2 | {...} | taint.cpp:243:11:246:2 | [...](...){...} | TAINT | +| taint.cpp:243:15:243:15 | `this` parameter in operator() | file://:0:0:0:0 | this | | +| taint.cpp:243:15:243:15 | `this` parameter in operator() | file://:0:0:0:0 | this | | | taint.cpp:249:11:252:2 | [...](...){...} | taint.cpp:253:2:253:2 | d | | | taint.cpp:249:18:249:18 | a | taint.cpp:250:8:250:8 | a | | | taint.cpp:249:25:249:25 | b | taint.cpp:251:8:251:8 | b | | @@ -228,7 +238,4 @@ | taint.cpp:255:19:255:19 | a | taint.cpp:256:8:256:8 | a | | | taint.cpp:255:27:255:27 | b | taint.cpp:257:8:257:8 | b | | | taint.cpp:258:7:258:12 | call to source | taint.cpp:258:3:258:14 | ... = ... | | -| taint.cpp:260:4:260:4 | ref arg t | taint.cpp:260:4:260:4 | t | | -| taint.cpp:260:7:260:7 | ref arg u | taint.cpp:260:7:260:7 | u | | -| taint.cpp:260:10:260:10 | ref arg w | taint.cpp:260:10:260:10 | w | | | taint.cpp:260:10:260:10 | ref arg w | taint.cpp:261:7:261:7 | w | | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp index 7be8038fe9f0..7c1ae15820d5 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp @@ -230,7 +230,7 @@ void test_lambdas() sink(u); return t; }; - sink(a()); // tainted [NOT DETECTED] + sink(a()); // tainted auto b = [&] { sink(t); // tainted [NOT DETECTED] diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected index 1810662ecf3d..c17e1d6e634f 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected @@ -1,3 +1,9 @@ +| file://:0:0:0:0 | t | taint.cpp:223:10:223:15 | call to source | +| file://:0:0:0:0 | t | taint.cpp:223:10:223:15 | call to source | +| file://:0:0:0:0 | t | taint.cpp:223:10:223:15 | call to source | +| file://:0:0:0:0 | u | taint.cpp:223:10:223:15 | call to source | +| file://:0:0:0:0 | u | taint.cpp:223:10:223:15 | call to source | +| file://:0:0:0:0 | u | taint.cpp:223:10:223:15 | call to source | | taint.cpp:8:8:8:13 | clean1 | taint.cpp:4:27:4:33 | source1 | | taint.cpp:16:8:16:14 | source1 | taint.cpp:12:22:12:27 | call to source | | taint.cpp:17:8:17:16 | ++ ... | taint.cpp:12:22:12:27 | call to source | @@ -20,5 +26,6 @@ | taint.cpp:210:7:210:7 | x | taint.cpp:207:6:207:11 | call to source | | taint.cpp:215:7:215:7 | x | taint.cpp:207:6:207:11 | call to source | | taint.cpp:216:7:216:7 | y | taint.cpp:207:6:207:11 | call to source | +| taint.cpp:233:8:233:8 | call to operator() | taint.cpp:223:10:223:15 | call to source | | taint.cpp:250:8:250:8 | a | taint.cpp:223:10:223:15 | call to source | | taint.cpp:256:8:256:8 | a | taint.cpp:223:10:223:15 | call to source | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected index dec5d64f5074..2c5d32f0f7be 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected @@ -1,3 +1,4 @@ +| file://:0:0:0:0 | taint.cpp:223:10:223:15 | AST only | | taint.cpp:41:7:41:13 | taint.cpp:35:12:35:17 | AST only | | taint.cpp:42:7:42:13 | taint.cpp:35:12:35:17 | AST only | | taint.cpp:43:7:43:13 | taint.cpp:37:22:37:27 | AST only | @@ -12,5 +13,6 @@ | taint.cpp:195:7:195:7 | taint.cpp:193:6:193:6 | AST only | | taint.cpp:215:7:215:7 | taint.cpp:207:6:207:11 | AST only | | taint.cpp:216:7:216:7 | taint.cpp:207:6:207:11 | AST only | +| taint.cpp:233:8:233:8 | taint.cpp:223:10:223:15 | AST only | | taint.cpp:250:8:250:8 | taint.cpp:223:10:223:15 | AST only | | taint.cpp:256:8:256:8 | taint.cpp:223:10:223:15 | AST only | From a6902bdb37d497f27273aaa8978eaca0959896a7 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 15 Aug 2019 19:43:24 +0100 Subject: [PATCH 3/3] CPP: Test dataflow through lambdas. --- .../dataflow/dataflow-tests/lambdas.cpp | 47 +++++++++++++++++++ .../dataflow/dataflow-tests/test.expected | 2 + .../dataflow-tests/test_diff.expected | 2 + 3 files changed, 51 insertions(+) create mode 100644 cpp/ql/test/library-tests/dataflow/dataflow-tests/lambdas.cpp diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/lambdas.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/lambdas.cpp new file mode 100644 index 000000000000..ce338d51f7f8 --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/lambdas.cpp @@ -0,0 +1,47 @@ +int source(); +void sink(...) {}; + +// --- lambdas --- + +void test_lambdas() +{ + int t = source(); + int u = 0; + int v = 0; + int w = 0; + + auto a = [t, u]() -> int { + sink(t); // flow from source() [NOT DETECTED] + sink(u); + return t; + }; + sink(a()); // flow from source() [NOT DETECTED] + + auto b = [&] { + sink(t); // flow from source() [NOT DETECTED] + sink(u); + v = source(); // (v is reference captured) + }; + b(); + sink(v); // flow from source() [NOT DETECTED] + + auto c = [=] { + sink(t); // flow from source() [NOT DETECTED] + sink(u); + }; + c(); + + auto d = [](int a, int b) { + sink(a); // flow from source() + sink(b); + }; + d(t, u); + + auto e = [](int &a, int &b, int &c) { + sink(a); // flow from source() + sink(b); + c = source(); + }; + e(t, u, w); + sink(w); // flow from source() [NOT DETECTED] +} 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 9968d63e3a88..80a256a1e57a 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected @@ -1,4 +1,6 @@ | acrossLinkTargets.cpp:12:8:12:8 | x | acrossLinkTargets.cpp:19:27:19:32 | call to source | +| lambdas.cpp:35:8:35:8 | a | lambdas.cpp:8:10:8:15 | call to source | +| lambdas.cpp:41:8:41: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 | | test.cpp:10:8:10:9 | t2 | test.cpp:6:12:6:17 | 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 6a2a933b6c7b..8145c1abb95b 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 @@ -1,3 +1,5 @@ +| lambdas.cpp:8:10:8:15 | lambdas.cpp:35:8:35:8 | AST only | +| lambdas.cpp:8:10:8:15 | lambdas.cpp:41:8:41:8 | AST only | | test.cpp:89:28:89:34 | test.cpp:92:8:92:14 | IR only | | test.cpp:100:13:100:18 | test.cpp:103:10:103:12 | AST only | | test.cpp:109:9:109:14 | test.cpp:110:10:110:12 | IR only |