mirror of
https://github.com/github/codeql.git
synced 2026-04-29 02:35:15 +02:00
C++: Replace the new rules in DataFlowUtil with a dataflow model for pointer wrapper classes.
This commit is contained in:
@@ -521,22 +521,6 @@ predicate localFlowStep(Node nodeFrom, Node nodeTo) {
|
||||
FieldFlow::fieldFlow(nodeFrom, nodeTo)
|
||||
}
|
||||
|
||||
private predicate pointerWrapperFlow(Node nodeFrom, Node nodeTo) {
|
||||
// post-update-smart-pointer-`operator->` -> `post-update`-qualifier
|
||||
exists(PointerWrapper wrapper, Call call |
|
||||
call = wrapper.getAnUnwrapperFunction().getACallToThisFunction() and
|
||||
nodeFrom.(PostUpdateNode).getPreUpdateNode().asExpr() = call and
|
||||
nodeTo.asDefiningArgument() = call.getQualifier()
|
||||
)
|
||||
or
|
||||
// smart-pointer-qualifier -> smart-pointer-`operator->`
|
||||
exists(PointerWrapper wrapper, Call call |
|
||||
call = wrapper.getAnUnwrapperFunction().getACallToThisFunction() and
|
||||
nodeFrom.asExpr() = call.getQualifier() and
|
||||
nodeTo.asExpr() = call
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: do not use.
|
||||
*
|
||||
@@ -602,8 +586,6 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
|
||||
nodeFrom.(PostUpdateNode).getPreUpdateNode().asExpr() = call and
|
||||
nodeTo.asDefiningArgument() = call.getQualifier()
|
||||
)
|
||||
or
|
||||
pointerWrapperFlow(nodeFrom, nodeTo)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import semmle.code.cpp.models.interfaces.Taint
|
||||
import semmle.code.cpp.models.interfaces.DataFlow
|
||||
import semmle.code.cpp.models.interfaces.PointerWrapper
|
||||
|
||||
/**
|
||||
@@ -14,6 +15,20 @@ private class UniqueOrSharedPtr extends Class, PointerWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
/** Any function that unwraps a pointer wrapper class to reveal the underlying pointer. */
|
||||
private class PointerWrapperDataFlow extends DataFlowFunction {
|
||||
PointerWrapperDataFlow() { this = any(PointerWrapper wrapper).getAnUnwrapperFunction() }
|
||||
|
||||
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
|
||||
input.isQualifierAddress() and output.isReturnValue()
|
||||
or
|
||||
input.isQualifierObject() and output.isReturnValueDeref()
|
||||
or
|
||||
input.isReturnValueDeref() and
|
||||
output.isQualifierObject()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The `std::make_shared` and `std::make_unique` template functions.
|
||||
*/
|
||||
|
||||
@@ -3308,6 +3308,15 @@
|
||||
| smart_pointer.cpp:83:8:83:8 | q | smart_pointer.cpp:83:9:83:9 | call to operator-> | |
|
||||
| smart_pointer.cpp:83:8:83:8 | ref arg q | smart_pointer.cpp:84:8:84:8 | q | |
|
||||
| smart_pointer.cpp:84:8:84:8 | q | smart_pointer.cpp:84:9:84:9 | call to operator-> | |
|
||||
| smart_pointer.cpp:87:17:87:18 | pa | smart_pointer.cpp:88:5:88:6 | pa | |
|
||||
| smart_pointer.cpp:88:5:88:20 | ... = ... | smart_pointer.cpp:88:9:88:9 | x [post update] | |
|
||||
| smart_pointer.cpp:88:13:88:18 | call to source | smart_pointer.cpp:88:5:88:20 | ... = ... | |
|
||||
| smart_pointer.cpp:92:25:92:50 | call to unique_ptr | smart_pointer.cpp:93:11:93:11 | p | |
|
||||
| smart_pointer.cpp:92:25:92:50 | call to unique_ptr | smart_pointer.cpp:94:8:94:8 | p | |
|
||||
| smart_pointer.cpp:93:11:93:11 | p | smart_pointer.cpp:93:13:93:15 | call to get | |
|
||||
| smart_pointer.cpp:93:11:93:11 | ref arg p | smart_pointer.cpp:94:8:94:8 | p | |
|
||||
| smart_pointer.cpp:93:13:93:15 | ref arg call to get | smart_pointer.cpp:93:11:93:11 | ref arg p | |
|
||||
| smart_pointer.cpp:94:8:94:8 | p | smart_pointer.cpp:94:9:94:9 | call to operator-> | |
|
||||
| standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:39:45:39:51 | source1 | |
|
||||
| standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:40:11:40:17 | source1 | |
|
||||
| standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:41:12:41:18 | source1 | |
|
||||
|
||||
@@ -9,7 +9,7 @@ template<typename T> void sink(std::unique_ptr<T>&);
|
||||
|
||||
void test_make_shared() {
|
||||
std::shared_ptr<int> p = std::make_shared<int>(source());
|
||||
sink(*p); // $ ast MISSING: ir
|
||||
sink(*p); // $ ast,ir
|
||||
sink(p); // $ ast,ir
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ void test_make_shared_array() {
|
||||
|
||||
void test_make_unique() {
|
||||
std::unique_ptr<int> p = std::make_unique<int>(source());
|
||||
sink(*p); // $ ast MISSING: ir
|
||||
sink(*p); // $ ast,ir
|
||||
sink(p); // $ ast,ir
|
||||
}
|
||||
|
||||
@@ -83,3 +83,13 @@ void test_operator_arrow(std::unique_ptr<A> p, std::unique_ptr<B> q) {
|
||||
sink(q->a1.y);
|
||||
sink(q->a2.x);
|
||||
}
|
||||
|
||||
void taint_x(A* pa) {
|
||||
pa->x = source();
|
||||
}
|
||||
|
||||
void reverse_taint_smart_pointer() {
|
||||
std::unique_ptr<A> p = std::unique_ptr<A>(new A);
|
||||
taint_x(p.get());
|
||||
sink(p->x); // $ ast MISSING: ir
|
||||
}
|
||||
Reference in New Issue
Block a user