Skip to content

Commit 978b74f

Browse files
committed
C++: Implement taint model for make_shared and make_unique
1 parent 7ac5e84 commit 978b74f

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

cpp/ql/src/semmle/code/cpp/models/Models.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ private import implementations.StdContainer
1818
private import implementations.StdString
1919
private import implementations.Swap
2020
private import implementations.GetDelim
21+
private import implementations.SmartPointer
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import semmle.code.cpp.models.interfaces.Taint
2+
3+
class UniqueOrSharedPtr extends Class {
4+
UniqueOrSharedPtr() { this.hasQualifiedName("std", ["shared_ptr", "unique_ptr"]) }
5+
}
6+
7+
class MakeUniqueOrShared extends TaintFunction {
8+
MakeUniqueOrShared() { this.hasQualifiedName("std", ["make_shared", "make_unique"]) }
9+
10+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
11+
// Exclude the `template<class T> shared_ptr<T[]> make_shared(std::size_t)` specialization
12+
// since we don't want to propagate taint via the size of the allocation.
13+
not this.isArray() and
14+
input.isParameter(_) and
15+
output.isReturnValue()
16+
}
17+
18+
/**
19+
* Holds if the function returns a `shared_ptr<T>` (or `unique_ptr<T>`) where `T` is an
20+
* array type (i.e., `U[]` for some type `U`).
21+
*/
22+
predicate isArray() {
23+
this.getTemplateArgument(0).(Type).getUnderlyingType() instanceof ArrayType
24+
}
25+
}
26+
27+
/**
28+
* A prefix `operator*` member function for a `shared_ptr` or `unique_ptr` type.
29+
*/
30+
class UniqueOrSharedDereferenceMemberOperator extends MemberFunction, TaintFunction {
31+
UniqueOrSharedDereferenceMemberOperator() {
32+
this.hasName("operator*") and
33+
this.getDeclaringType() instanceof UniqueOrSharedPtr
34+
}
35+
36+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
37+
input.isQualifierObject() and
38+
output.isReturnValueDeref()
39+
}
40+
}

0 commit comments

Comments
 (0)