Skip to content

Commit cae0060

Browse files
committed
C++: Replace the new rules in DataFlowUtil with a dataflow model for pointer wrapper classes.
1 parent 8382e85 commit cae0060

File tree

4 files changed

+36
-20
lines changed

4 files changed

+36
-20
lines changed

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

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -521,22 +521,6 @@ predicate localFlowStep(Node nodeFrom, Node nodeTo) {
521521
FieldFlow::fieldFlow(nodeFrom, nodeTo)
522522
}
523523

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-
540524
/**
541525
* INTERNAL: do not use.
542526
*
@@ -602,8 +586,6 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
602586
nodeFrom.(PostUpdateNode).getPreUpdateNode().asExpr() = call and
603587
nodeTo.asDefiningArgument() = call.getQualifier()
604588
)
605-
or
606-
pointerWrapperFlow(nodeFrom, nodeTo)
607589
}
608590

609591
/**

cpp/ql/src/semmle/code/cpp/models/implementations/SmartPointer.qll

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import semmle.code.cpp.models.interfaces.Taint
2+
import semmle.code.cpp.models.interfaces.DataFlow
23
import semmle.code.cpp.models.interfaces.PointerWrapper
34

45
/**
@@ -14,6 +15,20 @@ private class UniqueOrSharedPtr extends Class, PointerWrapper {
1415
}
1516
}
1617

18+
/** Any function that unwraps a pointer wrapper class to reveal the underlying pointer. */
19+
private class PointerWrapperDataFlow extends DataFlowFunction {
20+
PointerWrapperDataFlow() { this = any(PointerWrapper wrapper).getAnUnwrapperFunction() }
21+
22+
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
23+
input.isQualifierAddress() and output.isReturnValue()
24+
or
25+
input.isQualifierObject() and output.isReturnValueDeref()
26+
or
27+
input.isReturnValueDeref() and
28+
output.isQualifierObject()
29+
}
30+
}
31+
1732
/**
1833
* The `std::make_shared` and `std::make_unique` template functions.
1934
*/

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3308,6 +3308,15 @@
33083308
| smart_pointer.cpp:83:8:83:8 | q | smart_pointer.cpp:83:9:83:9 | call to operator-> | |
33093309
| smart_pointer.cpp:83:8:83:8 | ref arg q | smart_pointer.cpp:84:8:84:8 | q | |
33103310
| smart_pointer.cpp:84:8:84:8 | q | smart_pointer.cpp:84:9:84:9 | call to operator-> | |
3311+
| smart_pointer.cpp:87:17:87:18 | pa | smart_pointer.cpp:88:5:88:6 | pa | |
3312+
| smart_pointer.cpp:88:5:88:20 | ... = ... | smart_pointer.cpp:88:9:88:9 | x [post update] | |
3313+
| smart_pointer.cpp:88:13:88:18 | call to source | smart_pointer.cpp:88:5:88:20 | ... = ... | |
3314+
| smart_pointer.cpp:92:25:92:50 | call to unique_ptr | smart_pointer.cpp:93:11:93:11 | p | |
3315+
| smart_pointer.cpp:92:25:92:50 | call to unique_ptr | smart_pointer.cpp:94:8:94:8 | p | |
3316+
| smart_pointer.cpp:93:11:93:11 | p | smart_pointer.cpp:93:13:93:15 | call to get | |
3317+
| smart_pointer.cpp:93:11:93:11 | ref arg p | smart_pointer.cpp:94:8:94:8 | p | |
3318+
| smart_pointer.cpp:93:13:93:15 | ref arg call to get | smart_pointer.cpp:93:11:93:11 | ref arg p | |
3319+
| smart_pointer.cpp:94:8:94:8 | p | smart_pointer.cpp:94:9:94:9 | call to operator-> | |
33113320
| standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:39:45:39:51 | source1 | |
33123321
| standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:40:11:40:17 | source1 | |
33133322
| 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: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ template<typename T> void sink(std::unique_ptr<T>&);
99

1010
void test_make_shared() {
1111
std::shared_ptr<int> p = std::make_shared<int>(source());
12-
sink(*p); // $ ast MISSING: ir
12+
sink(*p); // $ ast,ir
1313
sink(p); // $ ast,ir
1414
}
1515

@@ -21,7 +21,7 @@ void test_make_shared_array() {
2121

2222
void test_make_unique() {
2323
std::unique_ptr<int> p = std::make_unique<int>(source());
24-
sink(*p); // $ ast MISSING: ir
24+
sink(*p); // $ ast,ir
2525
sink(p); // $ ast,ir
2626
}
2727

@@ -83,3 +83,13 @@ void test_operator_arrow(std::unique_ptr<A> p, std::unique_ptr<B> q) {
8383
sink(q->a1.y);
8484
sink(q->a2.x);
8585
}
86+
87+
void taint_x(A* pa) {
88+
pa->x = source();
89+
}
90+
91+
void reverse_taint_smart_pointer() {
92+
std::unique_ptr<A> p = std::unique_ptr<A>(new A);
93+
taint_x(p.get());
94+
sink(p->x); // $ ast MISSING: ir
95+
}

0 commit comments

Comments
 (0)