Skip to content

Commit 8382e85

Browse files
committed
C++: Add flow into the source of read step and out of the target of a store step for smart pointers in AST dataflow.
1 parent f07d844 commit 8382e85

File tree

3 files changed

+74
-36
lines changed

3 files changed

+74
-36
lines changed

cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ private import semmle.code.cpp.dataflow.internal.FlowVar
77
private import semmle.code.cpp.models.interfaces.DataFlow
88
private import semmle.code.cpp.controlflow.Guards
99
private import semmle.code.cpp.dataflow.internal.AddressFlow
10+
private import semmle.code.cpp.models.interfaces.PointerWrapper
1011

1112
cached
1213
private newtype TNode =
@@ -520,6 +521,22 @@ predicate localFlowStep(Node nodeFrom, Node nodeTo) {
520521
FieldFlow::fieldFlow(nodeFrom, nodeTo)
521522
}
522523

524+
private predicate pointerWrapperFlow(Node nodeFrom, Node nodeTo) {
525+
// post-update-smart-pointer-`operator->` -> `post-update`-qualifier
526+
exists(PointerWrapper wrapper, Call call |
527+
call = wrapper.getAnUnwrapperFunction().getACallToThisFunction() and
528+
nodeFrom.(PostUpdateNode).getPreUpdateNode().asExpr() = call and
529+
nodeTo.asDefiningArgument() = call.getQualifier()
530+
)
531+
or
532+
// smart-pointer-qualifier -> smart-pointer-`operator->`
533+
exists(PointerWrapper wrapper, Call call |
534+
call = wrapper.getAnUnwrapperFunction().getACallToThisFunction() and
535+
nodeFrom.asExpr() = call.getQualifier() and
536+
nodeTo.asExpr() = call
537+
)
538+
}
539+
523540
/**
524541
* INTERNAL: do not use.
525542
*
@@ -585,6 +602,8 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
585602
nodeFrom.(PostUpdateNode).getPreUpdateNode().asExpr() = call and
586603
nodeTo.asDefiningArgument() = call.getQualifier()
587604
)
605+
or
606+
pointerWrapperFlow(nodeFrom, nodeTo)
588607
}
589608

590609
/**

cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3223,72 +3223,91 @@
32233223
| smart_pointer.cpp:11:30:11:50 | call to make_shared | smart_pointer.cpp:12:11:12:11 | p | |
32243224
| smart_pointer.cpp:11:30:11:50 | call to make_shared | smart_pointer.cpp:13:10:13:10 | p | |
32253225
| smart_pointer.cpp:11:52:11:57 | call to source | smart_pointer.cpp:11:30:11:50 | call to make_shared | TAINT |
3226-
| smart_pointer.cpp:12:11:12:11 | p | smart_pointer.cpp:12:10:12:10 | call to operator* | TAINT |
3226+
| smart_pointer.cpp:12:11:12:11 | p | smart_pointer.cpp:12:10:12:10 | call to operator* | |
32273227
| smart_pointer.cpp:12:11:12:11 | ref arg p | smart_pointer.cpp:13:10:13:10 | p | |
32283228
| smart_pointer.cpp:17:32:17:54 | call to make_shared | smart_pointer.cpp:18:11:18:11 | p | |
32293229
| smart_pointer.cpp:17:32:17:54 | call to make_shared | smart_pointer.cpp:19:10:19:10 | p | |
3230-
| smart_pointer.cpp:18:11:18:11 | p | smart_pointer.cpp:18:10:18:10 | call to operator* | TAINT |
3230+
| smart_pointer.cpp:18:10:18:10 | ref arg call to operator* | smart_pointer.cpp:18:11:18:11 | ref arg p | |
3231+
| smart_pointer.cpp:18:11:18:11 | p | smart_pointer.cpp:18:10:18:10 | call to operator* | |
32313232
| smart_pointer.cpp:18:11:18:11 | ref arg p | smart_pointer.cpp:19:10:19:10 | p | |
32323233
| smart_pointer.cpp:23:30:23:50 | call to make_unique | smart_pointer.cpp:24:11:24:11 | p | |
32333234
| smart_pointer.cpp:23:30:23:50 | call to make_unique | smart_pointer.cpp:25:10:25:10 | p | |
32343235
| smart_pointer.cpp:23:52:23:57 | call to source | smart_pointer.cpp:23:30:23:50 | call to make_unique | TAINT |
3235-
| smart_pointer.cpp:24:11:24:11 | p | smart_pointer.cpp:24:10:24:10 | call to operator* | TAINT |
3236+
| smart_pointer.cpp:24:11:24:11 | p | smart_pointer.cpp:24:10:24:10 | call to operator* | |
32363237
| smart_pointer.cpp:24:11:24:11 | ref arg p | smart_pointer.cpp:25:10:25:10 | p | |
32373238
| smart_pointer.cpp:29:32:29:54 | call to make_unique | smart_pointer.cpp:30:11:30:11 | p | |
32383239
| smart_pointer.cpp:29:32:29:54 | call to make_unique | smart_pointer.cpp:31:10:31:10 | p | |
3239-
| smart_pointer.cpp:30:11:30:11 | p | smart_pointer.cpp:30:10:30:10 | call to operator* | TAINT |
3240+
| smart_pointer.cpp:30:10:30:10 | ref arg call to operator* | smart_pointer.cpp:30:11:30:11 | ref arg p | |
3241+
| smart_pointer.cpp:30:11:30:11 | p | smart_pointer.cpp:30:10:30:10 | call to operator* | |
32403242
| smart_pointer.cpp:30:11:30:11 | ref arg p | smart_pointer.cpp:31:10:31:10 | p | |
32413243
| smart_pointer.cpp:35:30:35:50 | call to make_shared | smart_pointer.cpp:37:6:37:6 | p | |
32423244
| smart_pointer.cpp:35:30:35:50 | call to make_shared | smart_pointer.cpp:38:10:38:10 | p | |
32433245
| smart_pointer.cpp:35:30:35:50 | call to make_shared | smart_pointer.cpp:39:11:39:11 | p | |
3246+
| smart_pointer.cpp:37:5:37:5 | call to operator* [post update] | smart_pointer.cpp:37:6:37:6 | ref arg p | |
32443247
| smart_pointer.cpp:37:5:37:17 | ... = ... | smart_pointer.cpp:37:5:37:5 | call to operator* [post update] | |
3245-
| smart_pointer.cpp:37:6:37:6 | p | smart_pointer.cpp:37:5:37:5 | call to operator* | TAINT |
3248+
| smart_pointer.cpp:37:6:37:6 | p | smart_pointer.cpp:37:5:37:5 | call to operator* | |
32463249
| smart_pointer.cpp:37:6:37:6 | ref arg p | smart_pointer.cpp:38:10:38:10 | p | |
32473250
| smart_pointer.cpp:37:6:37:6 | ref arg p | smart_pointer.cpp:39:11:39:11 | p | |
32483251
| smart_pointer.cpp:37:10:37:15 | call to source | smart_pointer.cpp:37:5:37:17 | ... = ... | |
32493252
| smart_pointer.cpp:38:10:38:10 | ref arg p | smart_pointer.cpp:39:11:39:11 | p | |
3250-
| smart_pointer.cpp:39:11:39:11 | p | smart_pointer.cpp:39:10:39:10 | call to operator* | TAINT |
3253+
| smart_pointer.cpp:39:11:39:11 | p | smart_pointer.cpp:39:10:39:10 | call to operator* | |
32513254
| smart_pointer.cpp:43:29:43:51 | call to unique_ptr | smart_pointer.cpp:45:6:45:6 | p | |
32523255
| smart_pointer.cpp:43:29:43:51 | call to unique_ptr | smart_pointer.cpp:46:10:46:10 | p | |
32533256
| smart_pointer.cpp:43:29:43:51 | call to unique_ptr | smart_pointer.cpp:47:11:47:11 | p | |
3257+
| smart_pointer.cpp:45:5:45:5 | call to operator* [post update] | smart_pointer.cpp:45:6:45:6 | ref arg p | |
32543258
| smart_pointer.cpp:45:5:45:17 | ... = ... | smart_pointer.cpp:45:5:45:5 | call to operator* [post update] | |
3255-
| smart_pointer.cpp:45:6:45:6 | p | smart_pointer.cpp:45:5:45:5 | call to operator* | TAINT |
3259+
| smart_pointer.cpp:45:6:45:6 | p | smart_pointer.cpp:45:5:45:5 | call to operator* | |
32563260
| smart_pointer.cpp:45:6:45:6 | ref arg p | smart_pointer.cpp:46:10:46:10 | p | |
32573261
| smart_pointer.cpp:45:6:45:6 | ref arg p | smart_pointer.cpp:47:11:47:11 | p | |
32583262
| smart_pointer.cpp:45:10:45:15 | call to source | smart_pointer.cpp:45:5:45:17 | ... = ... | |
32593263
| smart_pointer.cpp:46:10:46:10 | ref arg p | smart_pointer.cpp:47:11:47:11 | p | |
3260-
| smart_pointer.cpp:47:11:47:11 | p | smart_pointer.cpp:47:10:47:10 | call to operator* | TAINT |
3264+
| smart_pointer.cpp:47:11:47:11 | p | smart_pointer.cpp:47:10:47:10 | call to operator* | |
32613265
| smart_pointer.cpp:51:30:51:50 | call to make_shared | smart_pointer.cpp:52:10:52:10 | p | |
32623266
| smart_pointer.cpp:51:52:51:57 | call to source | smart_pointer.cpp:51:30:51:50 | call to make_shared | TAINT |
3263-
| smart_pointer.cpp:52:10:52:10 | p | smart_pointer.cpp:52:12:52:14 | call to get | TAINT |
3267+
| smart_pointer.cpp:52:10:52:10 | p | smart_pointer.cpp:52:12:52:14 | call to get | |
3268+
| smart_pointer.cpp:52:12:52:14 | ref arg call to get | smart_pointer.cpp:52:10:52:10 | ref arg p | |
32643269
| smart_pointer.cpp:56:30:56:50 | call to make_unique | smart_pointer.cpp:57:10:57:10 | p | |
32653270
| smart_pointer.cpp:56:52:56:57 | call to source | smart_pointer.cpp:56:30:56:50 | call to make_unique | TAINT |
3266-
| smart_pointer.cpp:57:10:57:10 | p | smart_pointer.cpp:57:12:57:14 | call to get | TAINT |
3271+
| smart_pointer.cpp:57:10:57:10 | p | smart_pointer.cpp:57:12:57:14 | call to get | |
3272+
| smart_pointer.cpp:57:12:57:14 | ref arg call to get | smart_pointer.cpp:57:10:57:10 | ref arg p | |
32673273
| smart_pointer.cpp:65:28:65:46 | call to make_unique | smart_pointer.cpp:66:10:66:10 | p | |
32683274
| smart_pointer.cpp:65:28:65:46 | call to make_unique | smart_pointer.cpp:67:10:67:10 | p | |
32693275
| smart_pointer.cpp:65:48:65:53 | call to source | smart_pointer.cpp:65:28:65:46 | call to make_unique | TAINT |
32703276
| smart_pointer.cpp:65:58:65:58 | 0 | smart_pointer.cpp:65:28:65:46 | call to make_unique | TAINT |
3277+
| smart_pointer.cpp:66:10:66:10 | p | smart_pointer.cpp:66:11:66:11 | call to operator-> | |
32713278
| smart_pointer.cpp:66:10:66:10 | ref arg p | smart_pointer.cpp:67:10:67:10 | p | |
3272-
| smart_pointer.cpp:76:45:76:45 | p | smart_pointer.cpp:77:5:77:5 | p | |
3273-
| smart_pointer.cpp:76:45:76:45 | p | smart_pointer.cpp:78:10:78:10 | p | |
3274-
| smart_pointer.cpp:76:45:76:45 | p | smart_pointer.cpp:79:10:79:10 | p | |
3275-
| smart_pointer.cpp:76:67:76:67 | q | smart_pointer.cpp:81:5:81:5 | q | |
3276-
| smart_pointer.cpp:76:67:76:67 | q | smart_pointer.cpp:82:10:82:10 | q | |
3277-
| smart_pointer.cpp:76:67:76:67 | q | smart_pointer.cpp:83:10:83:10 | q | |
3278-
| smart_pointer.cpp:76:67:76:67 | q | smart_pointer.cpp:84:10:84:10 | q | |
3279-
| smart_pointer.cpp:77:5:77:5 | ref arg p | smart_pointer.cpp:78:10:78:10 | p | |
3280-
| smart_pointer.cpp:77:5:77:5 | ref arg p | smart_pointer.cpp:79:10:79:10 | p | |
3281-
| smart_pointer.cpp:77:5:77:19 | ... = ... | smart_pointer.cpp:77:8:77:8 | x [post update] | |
3282-
| smart_pointer.cpp:77:12:77:17 | call to source | smart_pointer.cpp:77:5:77:19 | ... = ... | |
3283-
| smart_pointer.cpp:78:10:78:10 | ref arg p | smart_pointer.cpp:79:10:79:10 | p | |
3284-
| smart_pointer.cpp:81:5:81:5 | ref arg q | smart_pointer.cpp:82:10:82:10 | q | |
3285-
| smart_pointer.cpp:81:5:81:5 | ref arg q | smart_pointer.cpp:83:10:83:10 | q | |
3286-
| smart_pointer.cpp:81:5:81:5 | ref arg q | smart_pointer.cpp:84:10:84:10 | q | |
3287-
| smart_pointer.cpp:81:5:81:22 | ... = ... | smart_pointer.cpp:81:11:81:11 | x [post update] | |
3288-
| smart_pointer.cpp:81:15:81:20 | call to source | smart_pointer.cpp:81:5:81:22 | ... = ... | |
3289-
| smart_pointer.cpp:82:10:82:10 | ref arg q | smart_pointer.cpp:83:10:83:10 | q | |
3290-
| smart_pointer.cpp:82:10:82:10 | ref arg q | smart_pointer.cpp:84:10:84:10 | q | |
3291-
| smart_pointer.cpp:83:10:83:10 | ref arg q | smart_pointer.cpp:84:10:84:10 | q | |
3279+
| smart_pointer.cpp:67:10:67:10 | p | smart_pointer.cpp:67:11:67:11 | call to operator-> | |
3280+
| smart_pointer.cpp:76:45:76:45 | p | smart_pointer.cpp:77:3:77:3 | p | |
3281+
| smart_pointer.cpp:76:45:76:45 | p | smart_pointer.cpp:78:8:78:8 | p | |
3282+
| smart_pointer.cpp:76:45:76:45 | p | smart_pointer.cpp:79:8:79:8 | p | |
3283+
| smart_pointer.cpp:76:67:76:67 | q | smart_pointer.cpp:81:3:81:3 | q | |
3284+
| smart_pointer.cpp:76:67:76:67 | q | smart_pointer.cpp:82:8:82:8 | q | |
3285+
| smart_pointer.cpp:76:67:76:67 | q | smart_pointer.cpp:83:8:83:8 | q | |
3286+
| smart_pointer.cpp:76:67:76:67 | q | smart_pointer.cpp:84:8:84:8 | q | |
3287+
| smart_pointer.cpp:77:3:77:3 | p | smart_pointer.cpp:77:4:77:4 | call to operator-> | |
3288+
| smart_pointer.cpp:77:3:77:3 | ref arg p | smart_pointer.cpp:78:8:78:8 | p | |
3289+
| smart_pointer.cpp:77:3:77:3 | ref arg p | smart_pointer.cpp:79:8:79:8 | p | |
3290+
| smart_pointer.cpp:77:3:77:17 | ... = ... | smart_pointer.cpp:77:6:77:6 | x [post update] | |
3291+
| smart_pointer.cpp:77:3:77:17 | ... = ... | smart_pointer.cpp:78:11:78:11 | x | |
3292+
| smart_pointer.cpp:77:4:77:4 | call to operator-> [post update] | smart_pointer.cpp:77:3:77:3 | ref arg p | |
3293+
| smart_pointer.cpp:77:10:77:15 | call to source | smart_pointer.cpp:77:3:77:17 | ... = ... | |
3294+
| smart_pointer.cpp:78:8:78:8 | p | smart_pointer.cpp:78:9:78:9 | call to operator-> | |
3295+
| smart_pointer.cpp:78:8:78:8 | ref arg p | smart_pointer.cpp:79:8:79:8 | p | |
3296+
| smart_pointer.cpp:79:8:79:8 | p | smart_pointer.cpp:79:9:79:9 | call to operator-> | |
3297+
| smart_pointer.cpp:81:3:81:3 | q | smart_pointer.cpp:81:4:81:4 | call to operator-> | |
3298+
| smart_pointer.cpp:81:3:81:3 | ref arg q | smart_pointer.cpp:82:8:82:8 | q | |
3299+
| smart_pointer.cpp:81:3:81:3 | ref arg q | smart_pointer.cpp:83:8:83:8 | q | |
3300+
| smart_pointer.cpp:81:3:81:3 | ref arg q | smart_pointer.cpp:84:8:84:8 | q | |
3301+
| smart_pointer.cpp:81:3:81:20 | ... = ... | smart_pointer.cpp:81:9:81:9 | x [post update] | |
3302+
| smart_pointer.cpp:81:3:81:20 | ... = ... | smart_pointer.cpp:82:14:82:14 | x | |
3303+
| smart_pointer.cpp:81:4:81:4 | call to operator-> [post update] | smart_pointer.cpp:81:3:81:3 | ref arg q | |
3304+
| smart_pointer.cpp:81:13:81:18 | call to source | smart_pointer.cpp:81:3:81:20 | ... = ... | |
3305+
| smart_pointer.cpp:82:8:82:8 | q | smart_pointer.cpp:82:9:82:9 | call to operator-> | |
3306+
| smart_pointer.cpp:82:8:82:8 | ref arg q | smart_pointer.cpp:83:8:83:8 | q | |
3307+
| smart_pointer.cpp:82:8:82:8 | ref arg q | smart_pointer.cpp:84:8:84:8 | q | |
3308+
| smart_pointer.cpp:83:8:83:8 | q | smart_pointer.cpp:83:9:83:9 | call to operator-> | |
3309+
| smart_pointer.cpp:83:8:83:8 | ref arg q | smart_pointer.cpp:84:8:84:8 | q | |
3310+
| smart_pointer.cpp:84:8:84:8 | q | smart_pointer.cpp:84:9:84:9 | call to operator-> | |
32923311
| standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:39:45:39:51 | source1 | |
32933312
| standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:40:11:40:17 | source1 | |
32943313
| standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:41:12:41:18 | source1 | |

cpp/ql/test/library-tests/dataflow/taint-tests/smart_pointer.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,16 @@ void test_reverse_taint_shared() {
3535
std::shared_ptr<int> p = std::make_shared<int>();
3636

3737
*p = source();
38-
sink(p); // $ MISSING: ast,ir
39-
sink(*p); // $ MISSING: ast,ir
38+
sink(p); // $ ast MISSING: ir
39+
sink(*p); // $ ast MISSING: ir
4040
}
4141

4242
void test_reverse_taint_unique() {
4343
std::unique_ptr<int> p = std::unique_ptr<int>();
4444

4545
*p = source();
46-
sink(p); // $ MISSING: ast,ir
47-
sink(*p); // $ MISSING: ast,ir
46+
sink(p); // $ ast MISSING: ir
47+
sink(*p); // $ ast MISSING: ir
4848
}
4949

5050
void test_shared_get() {
@@ -75,11 +75,11 @@ struct B {
7575

7676
void test_operator_arrow(std::unique_ptr<A> p, std::unique_ptr<B> q) {
7777
p->x = source();
78-
sink(p->x); // $ MISSING: ast,ir
78+
sink(p->x); // $ ast MISSING: ir
7979
sink(p->y);
8080

8181
q->a1.x = source();
82-
sink(q->a1.x); // $ MISSING: ast,ir
82+
sink(q->a1.x); // $ ast MISSING: ir
8383
sink(q->a1.y);
8484
sink(q->a2.x);
8585
}

0 commit comments

Comments
 (0)