Skip to content

Commit 8226515

Browse files
committed
C++: Add a taint model for std::{shared, unique}_ptr<T>::get
1 parent 417424a commit 8226515

File tree

4 files changed

+41
-0
lines changed

4 files changed

+41
-0
lines changed

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,18 @@ class UniqueOrSharedDereferenceMemberOperator extends MemberFunction, TaintFunct
4444
output.isReturnValueDeref()
4545
}
4646
}
47+
48+
/**
49+
* The `std::shared_ptr` or `std::unique_ptr` function `get`.
50+
*/
51+
class UniqueOrSharedGet extends TaintFunction {
52+
UniqueOrSharedGet() {
53+
this.hasName("get") and
54+
this.getDeclaringType() instanceof UniqueOrSharedPtr
55+
}
56+
57+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
58+
input.isQualifierObject() and
59+
output.isReturnValue()
60+
}
61+
}

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,24 @@ void test_reverse_taint_unique() {
4545
*p = source();
4646
sink(p); // tainted [NOT DETECTED]
4747
sink(*p); // tainted [NOT DETECTED]
48+
}
49+
50+
void test_shared_get() {
51+
std::shared_ptr<int> p = std::make_shared<int>(source());
52+
sink(p.get()); // tainted
53+
}
54+
55+
void test_unique_get() {
56+
std::unique_ptr<int> p = std::make_unique<int>(source());
57+
sink(p.get()); // tainted
58+
}
59+
60+
struct A {
61+
int x, y;
62+
};
63+
64+
void test_shared_field_member() {
65+
std::unique_ptr<A> p = std::make_unique<A>(source(), 0);
66+
sink(p->x); // tainted [NOT DETECTED]
67+
sink(p->y); // not tainted
4868
}

cpp/ql/test/library-tests/dataflow/taint-tests/stl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,8 @@ namespace std {
241241

242242
T& operator*() const noexcept;
243243
T* operator->() const noexcept;
244+
245+
T* get() const noexcept;
244246
};
245247

246248
template<typename T>
@@ -254,6 +256,8 @@ namespace std {
254256

255257
T& operator*() const;
256258
T* operator->() const noexcept;
259+
260+
T* get() const noexcept;
257261
};
258262

259263
template<typename T, class... Args> unique_ptr<T> make_unique(Args&&...);

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
| smart_pointer.cpp:13:10:13:10 | p | smart_pointer.cpp:11:52:11:57 | call to source |
4242
| smart_pointer.cpp:24:10:24:10 | call to operator* | smart_pointer.cpp:23:52:23:57 | call to source |
4343
| smart_pointer.cpp:25:10:25:10 | p | smart_pointer.cpp:23:52:23:57 | call to source |
44+
| smart_pointer.cpp:52:12:52:14 | call to get | smart_pointer.cpp:51:52:51:57 | call to source |
45+
| smart_pointer.cpp:57:12:57:14 | call to get | smart_pointer.cpp:56:52:56:57 | call to source |
4446
| standalone_iterators.cpp:40:10:40:10 | call to operator* | standalone_iterators.cpp:39:45:39:51 | source1 |
4547
| standalone_iterators.cpp:41:10:41:10 | call to operator* | standalone_iterators.cpp:39:45:39:51 | source1 |
4648
| standalone_iterators.cpp:42:10:42:10 | call to operator* | standalone_iterators.cpp:39:45:39:51 | source1 |

0 commit comments

Comments
 (0)