Skip to content

Commit b14bc42

Browse files
authored
Merge pull request #4090 from geoffw0/strmethods
C++: Model taint through many more methods in std::string
2 parents a23bb6d + d76b25e commit b14bc42

File tree

7 files changed

+478
-5
lines changed

7 files changed

+478
-5
lines changed

change-notes/1.26/analysis-cpp.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@ The following changes in version 1.26 affect C/C++ analysis in all applications.
1919

2020
## Changes to libraries
2121

22-
* The models library now models more taint flows through `std::string`.
22+
* The models library now models many more taint flows through `std::string`.
2323
* The `SimpleRangeAnalysis` library now supports multiplications of the form
2424
`e1 * e2` when `e1` and `e2` are unsigned.

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

Lines changed: 82 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@ class StdBasicString extends TemplateClass {
88
}
99

1010
/**
11-
* The standard function `std::string.c_str`.
11+
* The `std::string` functions `c_str` and `data`.
1212
*/
1313
class StdStringCStr extends TaintFunction {
14-
StdStringCStr() { this.hasQualifiedName("std", "basic_string", "c_str") }
14+
StdStringCStr() {
15+
this.hasQualifiedName("std", "basic_string", "c_str") or
16+
this.hasQualifiedName("std", "basic_string", "data")
17+
}
1518

1619
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
1720
// flow from string itself (qualifier) to return value
@@ -40,12 +43,16 @@ class StdStringPlus extends TaintFunction {
4043
}
4144

4245
/**
43-
* The `std::string` functions `operator+=` and `append`.
46+
* The `std::string` functions `operator+=`, `append`, `insert` and
47+
* `replace`. All of these functions combine the existing string
48+
* with a new string (or character) from one of the arguments.
4449
*/
4550
class StdStringAppend extends TaintFunction {
4651
StdStringAppend() {
4752
this.hasQualifiedName("std", "basic_string", "operator+=") or
48-
this.hasQualifiedName("std", "basic_string", "append")
53+
this.hasQualifiedName("std", "basic_string", "append") or
54+
this.hasQualifiedName("std", "basic_string", "insert") or
55+
this.hasQualifiedName("std", "basic_string", "replace")
4956
}
5057

5158
/**
@@ -58,6 +65,35 @@ class StdStringAppend extends TaintFunction {
5865
getParameter(result).getType() = getDeclaringType().getTemplateArgument(0) // i.e. `std::basic_string::CharT`
5966
}
6067

68+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
69+
// flow from string and parameter to string (qualifier) and return value
70+
(
71+
input.isQualifierObject() or
72+
input.isParameterDeref(getAStringParameter())
73+
) and
74+
(
75+
output.isQualifierObject() or
76+
output.isReturnValueDeref()
77+
)
78+
}
79+
}
80+
81+
/**
82+
* The standard function `std::string.assign`.
83+
*/
84+
class StdStringAssign extends TaintFunction {
85+
StdStringAssign() { this.hasQualifiedName("std", "basic_string", "assign") }
86+
87+
/**
88+
* Gets the index of a parameter to this function that is a string (or
89+
* character).
90+
*/
91+
int getAStringParameter() {
92+
getParameter(result).getType() instanceof PointerType or
93+
getParameter(result).getType() instanceof ReferenceType or
94+
getParameter(result).getType() = getDeclaringType().getTemplateArgument(0) // i.e. `std::basic_string::CharT`
95+
}
96+
6197
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
6298
// flow from parameter to string itself (qualifier) and return value
6399
input.isParameterDeref(getAStringParameter()) and
@@ -67,3 +103,45 @@ class StdStringAppend extends TaintFunction {
67103
)
68104
}
69105
}
106+
107+
/**
108+
* The standard function `std::string.copy`.
109+
*/
110+
class StdStringCopy extends TaintFunction {
111+
StdStringCopy() { this.hasQualifiedName("std", "basic_string", "copy") }
112+
113+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
114+
// copy(dest, num, pos)
115+
input.isQualifierObject() and
116+
output.isParameterDeref(0)
117+
}
118+
}
119+
120+
/**
121+
* The standard function `std::string.substr`.
122+
*/
123+
class StdStringSubstr extends TaintFunction {
124+
StdStringSubstr() { this.hasQualifiedName("std", "basic_string", "substr") }
125+
126+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
127+
// substr(pos, num)
128+
input.isQualifierObject() and
129+
output.isReturnValue()
130+
}
131+
}
132+
133+
/**
134+
* The standard function `std::string.swap`.
135+
*/
136+
class StdStringSwap extends TaintFunction {
137+
StdStringSwap() { this.hasQualifiedName("std", "basic_string", "swap") }
138+
139+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
140+
// str1.swap(str2)
141+
input.isQualifierObject() and
142+
output.isParameterDeref(0)
143+
or
144+
input.isParameterDeref(0) and
145+
output.isQualifierObject()
146+
}
147+
}

0 commit comments

Comments
 (0)