Skip to content

Commit cbed175

Browse files
authored
Merge pull request github#3273 from Semmle/rdmarsh/cpp/RemoteFlowSource-model
C++: Add remote flow sources via models
2 parents 1312fcc + ac22e79 commit cbed175

File tree

4 files changed

+79
-2
lines changed

4 files changed

+79
-2
lines changed

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import semmle.code.cpp.models.interfaces.Alias
2+
import semmle.code.cpp.models.interfaces.FlowSource
23

3-
class Fread extends AliasFunction {
4+
class Fread extends AliasFunction, RemoteFlowFunction {
45
Fread() { this.hasGlobalName("fread") }
56

67
override predicate parameterNeverEscapes(int n) {
@@ -11,4 +12,9 @@ class Fread extends AliasFunction {
1112
override predicate parameterEscapesOnlyViaReturn(int n) { none() }
1213

1314
override predicate parameterIsAlwaysReturned(int n) { none() }
15+
16+
override predicate hasRemoteFlowSource(FunctionOutput output, string description) {
17+
output.isParameterDeref(0) and
18+
description = "String read by " + this.getName()
19+
}
1420
}

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ import semmle.code.cpp.models.interfaces.Taint
33
import semmle.code.cpp.models.interfaces.ArrayFunction
44
import semmle.code.cpp.models.interfaces.Alias
55
import semmle.code.cpp.models.interfaces.SideEffect
6+
import semmle.code.cpp.models.interfaces.FlowSource
67

78
/**
89
* The standard functions `gets` and `fgets`.
910
*/
1011
class GetsFunction extends DataFlowFunction, TaintFunction, ArrayFunction, AliasFunction,
11-
SideEffectFunction {
12+
SideEffectFunction, RemoteFlowFunction {
1213
GetsFunction() {
1314
exists(string name | hasGlobalOrStdName(name) |
1415
name = "gets" or // gets(str)
@@ -42,4 +43,9 @@ class GetsFunction extends DataFlowFunction, TaintFunction, ArrayFunction, Alias
4243
buffer = true and
4344
mustWrite = true
4445
}
46+
47+
override predicate hasRemoteFlowSource(FunctionOutput output, string description) {
48+
output.isParameterDeref(0) and
49+
description = "String read by " + this.getName()
50+
}
4551
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* Provides a class for modeling functions that return data from potentially untrusted sources. To use
3+
* this QL library, create a QL class extending `DataFlowFunction` with a
4+
* characteristic predicate that selects the function or set of functions you
5+
* are modeling. Within that class, override the predicates provided by
6+
* `RemoteFlowFunction` to match the flow within that function.
7+
*/
8+
9+
import cpp
10+
import FunctionInputsAndOutputs
11+
import semmle.code.cpp.models.Models
12+
13+
/**
14+
* A library function which returns data read from a network connection.
15+
*/
16+
abstract class RemoteFlowFunction extends Function {
17+
/**
18+
* Holds if remote data described by `description` flows from `output` of a call to this function.
19+
*/
20+
abstract predicate hasRemoteFlowSource(FunctionOutput output, string description);
21+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* Provides classes representing various flow sources for taint tracking.
3+
*/
4+
5+
import cpp
6+
import semmle.code.cpp.ir.dataflow.DataFlow
7+
private import semmle.code.cpp.ir.IR
8+
import semmle.code.cpp.models.interfaces.FlowSource
9+
10+
/** A data flow source of remote user input. */
11+
abstract class RemoteFlowSource extends DataFlow::Node {
12+
/** Gets a string that describes the type of this remote flow source. */
13+
abstract string getSourceType();
14+
}
15+
16+
private class TaintedReturnSource extends RemoteFlowSource {
17+
string sourceType;
18+
19+
TaintedReturnSource() {
20+
exists(RemoteFlowFunction func, CallInstruction instr, FunctionOutput output |
21+
asInstruction() = instr and
22+
instr.getStaticCallTarget() = func and
23+
func.hasRemoteFlowSource(output, sourceType) and
24+
output.isReturnValue()
25+
)
26+
}
27+
28+
override string getSourceType() { result = sourceType }
29+
}
30+
31+
private class TaintedParameterSource extends RemoteFlowSource {
32+
string sourceType;
33+
34+
TaintedParameterSource() {
35+
exists(RemoteFlowFunction func, WriteSideEffectInstruction instr, FunctionOutput output |
36+
asInstruction() = instr and
37+
instr.getPrimaryInstruction().(CallInstruction).getStaticCallTarget() = func and
38+
func.hasRemoteFlowSource(output, sourceType) and
39+
output.isParameterDeref(instr.getIndex())
40+
)
41+
}
42+
43+
override string getSourceType() { result = sourceType }
44+
}

0 commit comments

Comments
 (0)