Skip to content

Commit 3b7cf7f

Browse files
author
Robert Marsh
authored
Merge pull request #4439 from geoffw0/mapex
C++: Additional taint flows through std::map
2 parents fc4a342 + c63f7cb commit 3b7cf7f

File tree

6 files changed

+2104
-1653
lines changed

6 files changed

+2104
-1653
lines changed

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

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,58 @@ class StdMapInsert extends TaintFunction {
5252
}
5353

5454
/**
55-
* The standard map `swap` functions.
55+
* The standard map `emplace` and `emplace_hint` functions.
56+
*/
57+
class StdMapEmplace extends TaintFunction {
58+
StdMapEmplace() {
59+
this.hasQualifiedName("std", ["map", "unordered_map"], ["emplace", "emplace_hint"])
60+
}
61+
62+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
63+
// flow from the last parameter (which may be the value part used to
64+
// construct a pair, or a pair to be copied / moved) to the qualifier and
65+
// return value.
66+
// (where the return value is a pair, this should really flow just to the first part of it)
67+
input.isParameterDeref(getNumberOfParameters() - 1) and
68+
(
69+
output.isQualifierObject() or
70+
output.isReturnValue()
71+
)
72+
or
73+
input.isQualifierObject() and
74+
output.isReturnValue()
75+
}
76+
}
77+
78+
/**
79+
* The standard map `try_emplace` function.
80+
*/
81+
class StdMapTryEmplace extends TaintFunction {
82+
StdMapTryEmplace() { this.hasQualifiedName("std", ["map", "unordered_map"], "try_emplace") }
83+
84+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
85+
// flow from any parameter apart from the key to qualifier and return value
86+
// (here we assume taint flow from any constructor parameter to the constructed object)
87+
// (where the return value is a pair, this should really flow just to the first part of it)
88+
exists(int arg | arg = [1 .. getNumberOfParameters() - 1] |
89+
(
90+
not getUnspecifiedType() instanceof Iterator or
91+
arg != 1
92+
) and
93+
input.isParameterDeref(arg)
94+
) and
95+
(
96+
output.isQualifierObject() or
97+
output.isReturnValue()
98+
)
99+
or
100+
input.isQualifierObject() and
101+
output.isReturnValue()
102+
}
103+
}
104+
105+
/**
106+
* The standard map `swap` function.
56107
*/
57108
class StdMapSwap extends TaintFunction {
58109
StdMapSwap() { this.hasQualifiedName("std", ["map", "unordered_map"], "swap") }
@@ -67,6 +118,19 @@ class StdMapSwap extends TaintFunction {
67118
}
68119
}
69120

121+
/**
122+
* The standard map `merge` function.
123+
*/
124+
class StdMapMerge extends TaintFunction {
125+
StdMapMerge() { this.hasQualifiedName("std", ["map", "unordered_map"], "merge") }
126+
127+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
128+
// container1.merge(container2)
129+
input.isParameterDeref(0) and
130+
output.isQualifierObject()
131+
}
132+
}
133+
70134
/**
71135
* The standard map functions `at` and `operator[]`.
72136
*/
@@ -109,3 +173,20 @@ class StdMapErase extends TaintFunction {
109173
output.isReturnValue()
110174
}
111175
}
176+
177+
/**
178+
* The standard map `lower_bound`, `upper_bound` and `equal_range` functions.
179+
*/
180+
class StdMapEqualRange extends TaintFunction {
181+
StdMapEqualRange() {
182+
this
183+
.hasQualifiedName("std", ["map", "unordered_map"],
184+
["lower_bound", "upper_bound", "equal_range"])
185+
}
186+
187+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
188+
// flow from qualifier to return value
189+
input.isQualifierObject() and
190+
output.isReturnValue()
191+
}
192+
}

0 commit comments

Comments
 (0)