Skip to content

Commit 55d7ac8

Browse files
authored
Merge pull request #4148 from geoffw0/vecextra
C++: Improvements to string and vector models.
2 parents 80cb8be + 9b3da1f commit 55d7ac8

File tree

8 files changed

+370
-20
lines changed

8 files changed

+370
-20
lines changed

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

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class StdSequenceContainerConstructor extends Constructor, TaintFunction {
2323
*/
2424
int getAValueTypeParameterIndex() {
2525
getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
26-
getDeclaringType().getTemplateArgument(0) // i.e. the `T` of this `std::vector<T>`
26+
getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector<T>`
2727
}
2828

2929
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
@@ -33,6 +33,24 @@ class StdSequenceContainerConstructor extends Constructor, TaintFunction {
3333
}
3434
}
3535

36+
/**
37+
* The standard container function `data`.
38+
*/
39+
class StdSequenceContainerData extends TaintFunction {
40+
StdSequenceContainerData() { this.hasQualifiedName("std", ["array", "vector"], "data") }
41+
42+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
43+
// flow from container itself (qualifier) to return value
44+
input.isQualifierObject() and
45+
output.isReturnValueDeref()
46+
or
47+
// reverse flow from returned reference to the qualifier (for writes to
48+
// `data`)
49+
input.isReturnValueDeref() and
50+
output.isQualifierObject()
51+
}
52+
}
53+
3654
/**
3755
* The standard container functions `push_back` and `push_front`.
3856
*/
@@ -70,6 +88,30 @@ class StdSequenceContainerFrontBack extends TaintFunction {
7088
}
7189
}
7290

91+
/**
92+
* The standard container function `assign`.
93+
*/
94+
class StdSequenceContainerAssign extends TaintFunction {
95+
StdSequenceContainerAssign() {
96+
this.hasQualifiedName("std", ["vector", "deque", "list", "forward_list"], "assign")
97+
}
98+
99+
/**
100+
* Gets the index of a parameter to this function that is a reference to the
101+
* value type of the container.
102+
*/
103+
int getAValueTypeParameterIndex() {
104+
getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
105+
getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector<T>`
106+
}
107+
108+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
109+
// flow from parameter to string itself (qualifier) and return value
110+
input.isParameterDeref(getAValueTypeParameterIndex()) and
111+
output.isQualifierObject()
112+
}
113+
}
114+
73115
/**
74116
* The standard container `swap` functions.
75117
*/

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

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,33 @@ class StdBasicString extends TemplateClass {
88
}
99

1010
/**
11-
* The `std::string` functions `c_str` and `data`.
11+
* The `std::string` function `c_str`.
1212
*/
1313
class StdStringCStr extends TaintFunction {
14-
StdStringCStr() { this.hasQualifiedName("std", "basic_string", ["c_str", "data"]) }
14+
StdStringCStr() { this.hasQualifiedName("std", "basic_string", "c_str") }
1515

1616
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
1717
// flow from string itself (qualifier) to return value
1818
input.isQualifierObject() and
19-
output.isReturnValue()
19+
output.isReturnValueDeref()
20+
}
21+
}
22+
23+
/**
24+
* The `std::string` function `data`.
25+
*/
26+
class StdStringData extends TaintFunction {
27+
StdStringData() { this.hasQualifiedName("std", "basic_string", "data") }
28+
29+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
30+
// flow from string itself (qualifier) to return value
31+
input.isQualifierObject() and
32+
output.isReturnValueDeref()
33+
or
34+
// reverse flow from returned reference to the qualifier (for writes to
35+
// `data`)
36+
input.isReturnValueDeref() and
37+
output.isQualifierObject()
2038
}
2139
}
2240

@@ -53,17 +71,18 @@ class StdStringAppend extends TaintFunction {
5371
* Gets the index of a parameter to this function that is a string (or
5472
* character).
5573
*/
56-
int getAStringParameter() {
74+
int getAStringParameterIndex() {
5775
getParameter(result).getType() instanceof PointerType or
5876
getParameter(result).getType() instanceof ReferenceType or
59-
getParameter(result).getType() = getDeclaringType().getTemplateArgument(0) // i.e. `std::basic_string::CharT`
77+
getParameter(result).getUnspecifiedType() =
78+
getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. `std::basic_string::CharT`
6079
}
6180

6281
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
6382
// flow from string and parameter to string (qualifier) and return value
6483
(
6584
input.isQualifierObject() or
66-
input.isParameterDeref(getAStringParameter())
85+
input.isParameterDeref(getAStringParameterIndex())
6786
) and
6887
(
6988
output.isQualifierObject() or
@@ -82,15 +101,16 @@ class StdStringAssign extends TaintFunction {
82101
* Gets the index of a parameter to this function that is a string (or
83102
* character).
84103
*/
85-
int getAStringParameter() {
104+
int getAStringParameterIndex() {
86105
getParameter(result).getType() instanceof PointerType or
87106
getParameter(result).getType() instanceof ReferenceType or
88-
getParameter(result).getType() = getDeclaringType().getTemplateArgument(0) // i.e. `std::basic_string::CharT`
107+
getParameter(result).getUnspecifiedType() =
108+
getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. `std::basic_string::CharT`
89109
}
90110

91111
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
92112
// flow from parameter to string itself (qualifier) and return value
93-
input.isParameterDeref(getAStringParameter()) and
113+
input.isParameterDeref(getAStringParameterIndex()) and
94114
(
95115
output.isQualifierObject() or
96116
output.isReturnValueDeref()

0 commit comments

Comments
 (0)