Skip to content

Commit 297f1c7

Browse files
authored
Merge pull request #4345 from geoffw0/map
C++: Models for std::pair, std::map and std::unordered_map
2 parents 4ec14b1 + 855d2b5 commit 297f1c7

File tree

10 files changed

+2498
-7
lines changed

10 files changed

+2498
-7
lines changed

change-notes/1.26/analysis-cpp.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,6 @@ The following changes in version 1.26 affect C/C++ analysis in all applications.
2525
* The models library now models many more taint flows through `std::string`.
2626
* The models library now models many taint flows through `std::istream` and `std::ostream`.
2727
* The models library now models some taint flows through `std::shared_ptr`, `std::unique_ptr`, `std::make_shared` and `std::make_unique`.
28+
* The models library now models some taint flows through `std::pair`, `std::map` and `std::unordered_map`.
2829
* The `SimpleRangeAnalysis` library now supports multiplications of the form
2930
`e1 * e2` and `x *= e2` when `e1` and `e2` are unsigned or constant.

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ private import implementations.Strcpy
1515
private import implementations.Strdup
1616
private import implementations.Strftime
1717
private import implementations.StdContainer
18+
private import implementations.StdPair
19+
private import implementations.StdMap
1820
private import implementations.StdString
1921
private import implementations.Swap
2022
private import implementations.GetDelim
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/**
2+
* Provides models for C++ containers `std::map` and `std::unordered_map`.
3+
*/
4+
5+
import semmle.code.cpp.models.interfaces.Taint
6+
import semmle.code.cpp.models.implementations.Iterator
7+
8+
/**
9+
* The standard map `insert` and `insert_or_assign` functions.
10+
*/
11+
class StdMapInsert extends TaintFunction {
12+
StdMapInsert() {
13+
this.hasQualifiedName("std", ["map", "unordered_map"], ["insert", "insert_or_assign"])
14+
}
15+
16+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
17+
// flow from last parameter to qualifier and return value
18+
// (where the return value is a pair, this should really flow just to the first part of it)
19+
input.isParameterDeref(getNumberOfParameters() - 1) and
20+
(
21+
output.isQualifierObject() or
22+
output.isReturnValue()
23+
)
24+
}
25+
}
26+
27+
/**
28+
* The standard map `swap` functions.
29+
*/
30+
class StdMapSwap extends TaintFunction {
31+
StdMapSwap() { this.hasQualifiedName("std", ["map", "unordered_map"], "swap") }
32+
33+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
34+
// container1.swap(container2)
35+
input.isQualifierObject() and
36+
output.isParameterDeref(0)
37+
or
38+
input.isParameterDeref(0) and
39+
output.isQualifierObject()
40+
}
41+
}
42+
43+
/**
44+
* The standard map functions `at` and `operator[]`.
45+
*/
46+
class StdMapAt extends TaintFunction {
47+
StdMapAt() { this.hasQualifiedName("std", ["map", "unordered_map"], ["at", "operator[]"]) }
48+
49+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
50+
// flow from qualifier to referenced return value
51+
input.isQualifierObject() and
52+
output.isReturnValueDeref()
53+
or
54+
// reverse flow from returned reference to the qualifier
55+
input.isReturnValueDeref() and
56+
output.isQualifierObject()
57+
}
58+
}
59+
60+
/**
61+
* The standard map `find` function.
62+
*/
63+
class StdMapFind extends TaintFunction {
64+
StdMapFind() { this.hasQualifiedName("std", ["map", "unordered_map"], "find") }
65+
66+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
67+
input.isQualifierObject() and
68+
output.isReturnValue()
69+
}
70+
}
71+
72+
/**
73+
* The standard map `erase` function.
74+
*/
75+
class StdMapErase extends TaintFunction {
76+
StdMapErase() { this.hasQualifiedName("std", ["map", "unordered_map"], "erase") }
77+
78+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
79+
// flow from qualifier to iterator return value
80+
getType().getUnderlyingType() instanceof Iterator and
81+
input.isQualifierObject() and
82+
output.isReturnValue()
83+
}
84+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* Provides models for the C++ `std::pair` class.
3+
*/
4+
5+
import semmle.code.cpp.models.interfaces.Taint
6+
7+
/**
8+
* Additional model for `std::pair` constructors.
9+
*/
10+
class StdPairConstructor extends Constructor, TaintFunction {
11+
StdPairConstructor() { this.hasQualifiedName("std", "pair", "pair") }
12+
13+
/**
14+
* Gets the index of a parameter to this function that is a reference to
15+
* either value type of the pair.
16+
*/
17+
int getAValueTypeParameterIndex() {
18+
getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
19+
getDeclaringType().getTemplateArgument(_).(Type).getUnspecifiedType() // i.e. the `T1` or `T2` of this `std::pair<T1, T2>`
20+
}
21+
22+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
23+
// taint flow from second parameter of a value type to the qualifier
24+
getAValueTypeParameterIndex() = 1 and
25+
input.isParameterDeref(1) and
26+
(
27+
output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object
28+
or
29+
output.isQualifierObject()
30+
)
31+
}
32+
}
33+
34+
/**
35+
* The standard pair `swap` function.
36+
*/
37+
class StdPairSwap extends TaintFunction {
38+
StdPairSwap() { this.hasQualifiedName("std", "pair", "swap") }
39+
40+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
41+
// container1.swap(container2)
42+
input.isQualifierObject() and
43+
output.isParameterDeref(0)
44+
or
45+
input.isParameterDeref(0) and
46+
output.isQualifierObject()
47+
}
48+
}

0 commit comments

Comments
 (0)