Skip to content

Commit 362c12c

Browse files
authored
Merge pull request github#5217 from MathiasVP/model-bsd-sockets-part-3
C++: Implement models for poll, accept and select
2 parents 110f407 + f908d2f commit 362c12c

File tree

6 files changed

+178
-0
lines changed

6 files changed

+178
-0
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,6 @@ private import implementations.SmartPointer
3030
private import implementations.Sscanf
3131
private import implementations.Send
3232
private import implementations.Recv
33+
private import implementations.Accept
34+
private import implementations.Poll
35+
private import implementations.Select
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* Provides implementation classes modeling `accept` and various similar
3+
* functions. See `semmle.code.cpp.models.Models` for usage information.
4+
*/
5+
6+
import semmle.code.cpp.Function
7+
import semmle.code.cpp.models.interfaces.ArrayFunction
8+
import semmle.code.cpp.models.interfaces.Taint
9+
import semmle.code.cpp.models.interfaces.Alias
10+
import semmle.code.cpp.models.interfaces.SideEffect
11+
12+
/**
13+
* The function `accept` and its assorted variants
14+
*/
15+
private class Accept extends ArrayFunction, AliasFunction, TaintFunction, SideEffectFunction {
16+
Accept() { this.hasGlobalName(["accept", "accept4", "WSAAccept"]) }
17+
18+
override predicate hasArrayWithVariableSize(int bufParam, int countParam) {
19+
bufParam = 1 and countParam = 2
20+
}
21+
22+
override predicate hasArrayInput(int bufParam) { bufParam = 1 }
23+
24+
override predicate hasArrayOutput(int bufParam) { bufParam = 1 }
25+
26+
override predicate parameterNeverEscapes(int index) { exists(this.getParameter(index)) }
27+
28+
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
29+
30+
override predicate parameterIsAlwaysReturned(int index) { none() }
31+
32+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
33+
(input.isParameter(0) or input.isParameterDeref(1)) and
34+
(output.isReturnValue() or output.isParameterDeref(1))
35+
}
36+
37+
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
38+
i = 1 and buffer = true and mustWrite = false
39+
or
40+
i = 2 and buffer = false and mustWrite = false
41+
}
42+
43+
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
44+
i = 0 and buffer = true
45+
or
46+
i = 1 and buffer = false
47+
}
48+
49+
override ParameterIndex getParameterSizeIndex(ParameterIndex i) { i = 1 and result = 2 }
50+
51+
// NOTE: We implement thse two predicates as none because we can't model the low-level changes made to
52+
// the structure pointed to by the file-descriptor argument.
53+
override predicate hasOnlySpecificReadSideEffects() { none() }
54+
55+
override predicate hasOnlySpecificWriteSideEffects() { none() }
56+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* Provides implementation classes modeling `poll` and various similar
3+
* functions. See `semmle.code.cpp.models.Models` for usage information.
4+
*/
5+
6+
import semmle.code.cpp.Function
7+
import semmle.code.cpp.models.interfaces.ArrayFunction
8+
import semmle.code.cpp.models.interfaces.Alias
9+
import semmle.code.cpp.models.interfaces.SideEffect
10+
11+
/**
12+
* The function `poll` and its assorted variants
13+
*/
14+
private class Poll extends ArrayFunction, AliasFunction, SideEffectFunction {
15+
Poll() { this.hasGlobalName(["poll", "ppoll", "WSAPoll"]) }
16+
17+
override predicate hasArrayWithVariableSize(int bufParam, int countParam) {
18+
bufParam = 0 and countParam = 1
19+
}
20+
21+
override predicate hasArrayInput(int bufParam) { bufParam = 0 }
22+
23+
override predicate hasArrayOutput(int bufParam) { bufParam = 0 }
24+
25+
override predicate parameterNeverEscapes(int index) { exists(this.getParameter(index)) }
26+
27+
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
28+
29+
override predicate parameterIsAlwaysReturned(int index) { none() }
30+
31+
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
32+
i = 0 and buffer = true and mustWrite = false
33+
}
34+
35+
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
36+
i = 0 and buffer = true
37+
or
38+
this.hasGlobalName("ppoll") and i = [2, 3] and buffer = false
39+
}
40+
41+
override predicate hasOnlySpecificReadSideEffects() { any() }
42+
43+
override predicate hasOnlySpecificWriteSideEffects() { any() }
44+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* Provides implementation classes modeling `select` and various similar
3+
* functions. See `semmle.code.cpp.models.Models` for usage information.
4+
*/
5+
6+
import semmle.code.cpp.Function
7+
import semmle.code.cpp.models.interfaces.ArrayFunction
8+
import semmle.code.cpp.models.interfaces.Alias
9+
import semmle.code.cpp.models.interfaces.SideEffect
10+
11+
/**
12+
* The function `select` and its assorted variants
13+
*/
14+
private class Select extends ArrayFunction, AliasFunction, SideEffectFunction {
15+
Select() { this.hasGlobalName(["select", "pselect"]) }
16+
17+
override predicate hasArrayWithUnknownSize(int bufParam) { bufParam = [1 .. 3] }
18+
19+
override predicate hasArrayInput(int bufParam) { bufParam = [1 .. 3] }
20+
21+
override predicate hasArrayOutput(int bufParam) { bufParam = [1 .. 3] }
22+
23+
override predicate parameterNeverEscapes(int index) { exists(this.getParameter(index)) }
24+
25+
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
26+
27+
override predicate parameterIsAlwaysReturned(int index) { none() }
28+
29+
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
30+
i = [1 .. 3] and buffer = true and mustWrite = false
31+
}
32+
33+
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
34+
i = [1 .. 5] and buffer = true
35+
}
36+
37+
override predicate hasOnlySpecificReadSideEffects() { any() }
38+
39+
override predicate hasOnlySpecificWriteSideEffects() { any() }
40+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
void sink(...);
2+
int source();
3+
4+
// --- accept ---
5+
6+
struct sockaddr {
7+
unsigned char length;
8+
int sa_family;
9+
char* sa_data;
10+
};
11+
12+
int accept(int, const sockaddr*, int*);
13+
14+
void sink(sockaddr);
15+
16+
void test_accept() {
17+
int s = source();
18+
sockaddr addr;
19+
int size = sizeof(sockaddr);
20+
int a = accept(s, &addr, &size);
21+
22+
sink(a); // $ ast=17:11 SPURIOUS: ast=18:12 MISSING: ir
23+
sink(addr); // $ ast MISSING: ir
24+
}

cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,17 @@
135135
| arrayassignment.cpp:145:12:145:12 | 5 | arrayassignment.cpp:145:7:145:13 | access to array | TAINT |
136136
| arrayassignment.cpp:146:7:146:10 | arr3 | arrayassignment.cpp:146:7:146:13 | access to array | |
137137
| arrayassignment.cpp:146:12:146:12 | 5 | arrayassignment.cpp:146:7:146:13 | access to array | TAINT |
138+
| bsd.cpp:17:11:17:16 | call to source | bsd.cpp:20:18:20:18 | s | |
139+
| bsd.cpp:18:12:18:15 | addr | bsd.cpp:20:22:20:25 | addr | |
140+
| bsd.cpp:18:12:18:15 | addr | bsd.cpp:23:8:23:11 | addr | |
141+
| bsd.cpp:19:14:19:29 | sizeof(sockaddr) | bsd.cpp:20:29:20:32 | size | |
142+
| bsd.cpp:20:11:20:16 | call to accept | bsd.cpp:22:8:22:8 | a | |
143+
| bsd.cpp:20:18:20:18 | s | bsd.cpp:20:11:20:16 | call to accept | TAINT |
144+
| bsd.cpp:20:21:20:25 | & ... | bsd.cpp:20:11:20:16 | call to accept | TAINT |
145+
| bsd.cpp:20:22:20:25 | addr | bsd.cpp:20:11:20:16 | call to accept | TAINT |
146+
| bsd.cpp:20:22:20:25 | addr | bsd.cpp:20:21:20:25 | & ... | |
147+
| bsd.cpp:20:28:20:32 | ref arg & ... | bsd.cpp:20:29:20:32 | size [inner post update] | |
148+
| bsd.cpp:20:29:20:32 | size | bsd.cpp:20:28:20:32 | & ... | |
138149
| constructor_delegation.cpp:8:2:8:8 | this | constructor_delegation.cpp:8:20:8:24 | constructor init of field x [pre-this] | |
139150
| constructor_delegation.cpp:8:14:8:15 | _x | constructor_delegation.cpp:8:22:8:23 | _x | |
140151
| constructor_delegation.cpp:8:22:8:23 | _x | constructor_delegation.cpp:8:20:8:24 | constructor init of field x | TAINT |

0 commit comments

Comments
 (0)