C++: Support flow through LambdaExpression

I've checked with a temporary workaround for the locations problem that
my annotations in the test cpp files are on the correct lines.
This commit is contained in:
Jonas Jensen
2019-08-16 15:33:33 +02:00
parent 0df9a625ba
commit 84adeda167
6 changed files with 28 additions and 17 deletions

View File

@@ -452,6 +452,11 @@ private predicate exprToExprStep_nocfg(Expr fromExpr, Expr toExpr) {
// initializer `(x)`.
toExpr.(NewExpr).getInitializer() = fromExpr
or
// A lambda expression (`[captures](params){body}`) is just a thin wrapper
// around the desugared closure creation in the form of a
// `ClassAggregateLiteral` (`{ capture1, ..., captureN }`).
toExpr.(LambdaExpression).getInitializer() = fromExpr
or
toExpr = any(Call call |
exists(DataFlowFunction f, FunctionInput inModel, FunctionOutput outModel, int iIn |
call.getTarget() = f and

View File

@@ -11,14 +11,14 @@ void test_lambdas()
int w = 0;
auto a = [t, u]() -> int {
sink(t); // flow from source() [NOT DETECTED]
sink(t); // flow from source()
sink(u);
return t;
};
sink(a()); // flow from source() [NOT DETECTED]
sink(a()); // flow from source()
auto b = [&] {
sink(t); // flow from source() [NOT DETECTED]
sink(t); // flow from source()
sink(u);
v = source(); // (v is reference captured)
};
@@ -26,7 +26,7 @@ void test_lambdas()
sink(v); // flow from source() [NOT DETECTED]
auto c = [=] {
sink(t); // flow from source() [NOT DETECTED]
sink(t); // flow from source()
sink(u);
};
c();

View File

@@ -1,4 +1,8 @@
| acrossLinkTargets.cpp:12:8:12:8 | x | acrossLinkTargets.cpp:19:27:19:32 | call to source |
| file://:0:0:0:0 | t | lambdas.cpp:8:10:8:15 | call to source |
| file://:0:0:0:0 | t | lambdas.cpp:8:10:8:15 | call to source |
| file://:0:0:0:0 | 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: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 |

View File

@@ -1,3 +1,5 @@
| lambdas.cpp:8:10:8:15 | file://:0:0:0:0 | AST only |
| lambdas.cpp:8:10:8:15 | lambdas.cpp:18:8:18:8 | AST only |
| 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 |

View File

@@ -213,7 +213,7 @@
| 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:11:232:2 | {...} | taint.cpp:228:11:232:2 | [...](...){...} | |
| 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 | |
@@ -222,13 +222,13 @@
| 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:11:239:2 | {...} | taint.cpp:235:11:239:2 | [...](...){...} | |
| 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:11:246:2 | {...} | taint.cpp:243:11:246:2 | [...](...){...} | |
| 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 | |

View File

@@ -208,11 +208,11 @@ void test_swap() {
y = 0;
sink(x); // tainted
sink(y);
sink(y); // clean
std::swap(x, y);
sink(x); // [FALSE POSITIVE]
sink(x); // clean [FALSE POSITIVE]
sink(y); // tainted
}
@@ -226,35 +226,35 @@ void test_lambdas()
int w = 0;
auto a = [t, u]() -> int {
sink(t); // tainted [NOT DETECTED]
sink(u);
sink(t); // tainted
sink(u); // clean [FALSE POSITIVE]
return t;
};
sink(a()); // tainted
auto b = [&] {
sink(t); // tainted [NOT DETECTED]
sink(u);
sink(t); // tainted
sink(u); // clean [FALSE POSITIVE]
v = source(); // (v is reference captured)
};
b();
sink(v); // tainted [NOT DETECTED]
auto c = [=] {
sink(t); // tainted [NOT DETECTED]
sink(u);
sink(t); // tainted
sink(u); // clean [FALSE POSITIVE]
};
c();
auto d = [](int a, int b) {
sink(a); // tainted
sink(b);
sink(b); // clean
};
d(t, u);
auto e = [](int &a, int &b, int &c) {
sink(a); // tainted
sink(b);
sink(b); // clean
c = source();
};
e(t, u, w);