Skip to content

Commit 50cd759

Browse files
authored
Merge pull request github#3733 from geoffw0/models5
C++: Constructor and assignment models
2 parents 38b73ff + 168f940 commit 50cd759

File tree

11 files changed

+586
-14
lines changed

11 files changed

+586
-14
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
@@ -4,6 +4,7 @@ private import implementations.Fread
44
private import implementations.Gets
55
private import implementations.IdentityFunction
66
private import implementations.Inet
7+
private import implementations.MemberFunction
78
private import implementations.Memcpy
89
private import implementations.Memset
910
private import implementations.Printf
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/**
2+
* Provides models for C++ constructors and user-defined operators.
3+
*/
4+
5+
import cpp
6+
import semmle.code.cpp.models.interfaces.DataFlow
7+
import semmle.code.cpp.models.interfaces.Taint
8+
9+
/**
10+
* Model for C++ conversion constructors.
11+
*/
12+
class ConversionConstructorModel extends ConversionConstructor, TaintFunction {
13+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
14+
// taint flow from the first constructor argument to the returned object
15+
input.isParameter(0) and
16+
output.isReturnValue() // TODO: this should be `isQualifierObject` by our current definitions, but that flow is not yet supported.
17+
}
18+
}
19+
20+
/**
21+
* Model for C++ copy constructors.
22+
*/
23+
class CopyConstructorModel extends CopyConstructor, DataFlowFunction {
24+
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
25+
// data flow from the first constructor argument to the returned object
26+
input.isParameter(0) and
27+
output.isReturnValue() // TODO: this should be `isQualifierObject` by our current definitions, but that flow is not yet supported.
28+
}
29+
}
30+
31+
/**
32+
* Model for C++ move constructors.
33+
*/
34+
class MoveConstructorModel extends MoveConstructor, DataFlowFunction {
35+
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
36+
// data flow from the first constructor argument to the returned object
37+
input.isParameter(0) and
38+
output.isReturnValue() // TODO: this should be `isQualifierObject` by our current definitions, but that flow is not yet supported.
39+
}
40+
}
41+
42+
/**
43+
* Model for C++ copy assignment operators.
44+
*/
45+
class CopyAssignmentOperatorModel extends CopyAssignmentOperator, TaintFunction {
46+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
47+
// taint flow from argument to self
48+
input.isParameterDeref(0) and
49+
output.isQualifierObject()
50+
or
51+
// taint flow from argument to return value
52+
input.isParameterDeref(0) and
53+
output.isReturnValueDeref()
54+
// TODO: it would be more accurate to model copy assignment as data flow
55+
}
56+
}
57+
58+
/**
59+
* Model for C++ move assignment operators.
60+
*/
61+
class MoveAssignmentOperatorModel extends MoveAssignmentOperator, TaintFunction {
62+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
63+
// taint flow from argument to self
64+
input.isParameterDeref(0) and
65+
output.isQualifierObject()
66+
or
67+
// taint flow from argument to return value
68+
input.isParameterDeref(0) and
69+
output.isReturnValueDeref()
70+
// TODO: it would be more accurate to model move assignment as data flow
71+
}
72+
}

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

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,5 @@
11
import semmle.code.cpp.models.interfaces.Taint
22

3-
/**
4-
* The `std::basic_string` constructor(s).
5-
*/
6-
class StdStringConstructor extends TaintFunction {
7-
pragma[noinline]
8-
StdStringConstructor() { this.hasQualifiedName("std", "basic_string", "basic_string") }
9-
10-
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
11-
// flow from any constructor argument to return value
12-
input.isParameter(_) and
13-
output.isReturnValue()
14-
}
15-
}
16-
173
/**
184
* The standard function `std::string.c_str`.
195
*/
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
2+
int source();
3+
void sink(...) {};
4+
5+
class MyCopyableClass {
6+
public:
7+
MyCopyableClass() {} // Constructor
8+
MyCopyableClass(int _v) : v(_v) {} // ConversionConstructor
9+
MyCopyableClass(const MyCopyableClass &other) : v(other.v) {} // CopyConstructor
10+
MyCopyableClass &operator=(const MyCopyableClass &other) { // CopyAssignmentOperator
11+
v = other.v;
12+
return *this;
13+
}
14+
15+
int v;
16+
};
17+
18+
void test_copyableclass()
19+
{
20+
{
21+
MyCopyableClass s1(1);
22+
MyCopyableClass s2 = 1;
23+
MyCopyableClass s3(s1);
24+
MyCopyableClass s4;
25+
s4 = 1;
26+
27+
sink(s1);
28+
sink(s2);
29+
sink(s3);
30+
sink(s4);
31+
}
32+
33+
{
34+
MyCopyableClass s1(source());
35+
MyCopyableClass s2 = source();
36+
MyCopyableClass s3(s1);
37+
MyCopyableClass s4;
38+
s4 = source();
39+
40+
sink(s1); // tainted
41+
sink(s2); // tainted
42+
sink(s3); // tainted
43+
sink(s4); // tainted
44+
}
45+
46+
{
47+
MyCopyableClass s1;
48+
MyCopyableClass s2 = s1;
49+
MyCopyableClass s3(s1);
50+
MyCopyableClass s4;
51+
s4 = s1;
52+
53+
sink(s1);
54+
sink(s2);
55+
sink(s3);
56+
sink(s4);
57+
}
58+
59+
{
60+
MyCopyableClass s1 = MyCopyableClass(source());
61+
MyCopyableClass s2;
62+
MyCopyableClass s3;
63+
s2 = MyCopyableClass(source());
64+
65+
sink(s1); // tainted
66+
sink(s2); // tainted
67+
sink(s3 = source()); // tainted
68+
}
69+
}

0 commit comments

Comments
 (0)