Skip to content

Commit 4326e6f

Browse files
committed
C++: Split 'gets' model and make it a local source.
1 parent 79735f5 commit 4326e6f

File tree

3 files changed

+52
-14
lines changed

3 files changed

+52
-14
lines changed

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

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,14 @@ import semmle.code.cpp.models.interfaces.SideEffect
1111
import semmle.code.cpp.models.interfaces.FlowSource
1212

1313
/**
14-
* The standard functions `gets` and `fgets`.
14+
* The standard functions `fgets` and `fgetws`.
1515
*/
16-
private class GetsFunction extends DataFlowFunction, TaintFunction, ArrayFunction, AliasFunction,
16+
private class FgetsFunction extends DataFlowFunction, TaintFunction, ArrayFunction, AliasFunction,
1717
SideEffectFunction, RemoteFlowSourceFunction {
18-
GetsFunction() {
19-
// gets(str)
18+
FgetsFunction() {
2019
// fgets(str, num, stream)
2120
// fgetws(wstr, num, stream)
22-
this.hasGlobalOrStdOrBslName(["gets", "fgets", "fgetws"])
21+
this.hasGlobalOrStdOrBslName(["fgets", "fgetws"])
2322
}
2423

2524
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
@@ -54,17 +53,60 @@ private class GetsFunction extends DataFlowFunction, TaintFunction, ArrayFunctio
5453
}
5554

5655
override predicate hasArrayWithVariableSize(int bufParam, int countParam) {
57-
not this.hasName("gets") and
5856
bufParam = 0 and
5957
countParam = 1
6058
}
6159

60+
override predicate hasArrayOutput(int bufParam) { bufParam = 0 }
61+
62+
override predicate hasSocketInput(FunctionInput input) { input.isParameter(2) }
63+
}
64+
65+
66+
/**
67+
* The standard functions `gets`.
68+
*/
69+
private class GetsFunction extends DataFlowFunction, TaintFunction, ArrayFunction, AliasFunction,
70+
SideEffectFunction, LocalFlowSourceFunction {
71+
GetsFunction() {
72+
// gets(str)
73+
this.hasGlobalOrStdOrBslName("gets")
74+
}
75+
76+
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
77+
input.isParameter(0) and
78+
output.isReturnValue()
79+
}
80+
81+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
82+
input.isParameter(2) and
83+
output.isParameterDeref(0)
84+
}
85+
86+
override predicate parameterNeverEscapes(int index) { none() }
87+
88+
override predicate parameterEscapesOnlyViaReturn(int index) { index = 0 }
89+
90+
override predicate parameterIsAlwaysReturned(int index) { index = 0 }
91+
92+
override predicate hasOnlySpecificReadSideEffects() { any() }
93+
94+
override predicate hasOnlySpecificWriteSideEffects() { any() }
95+
96+
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
97+
i = 0 and
98+
buffer = true and
99+
mustWrite = true
100+
}
101+
102+
override predicate hasLocalFlowSource(FunctionOutput output, string description) {
103+
output.isParameterDeref(0) and
104+
description = "String read by " + this.getName()
105+
}
106+
62107
override predicate hasArrayWithUnknownSize(int bufParam) {
63-
this.hasName("gets") and
64108
bufParam = 0
65109
}
66110

67111
override predicate hasArrayOutput(int bufParam) { bufParam = 0 }
68-
69-
override predicate hasSocketInput(FunctionInput input) { input.isParameter(2) }
70112
}

cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextTransmission.expected

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
edges
2-
| test2.cpp:101:8:101:15 | password | test2.cpp:103:8:103:15 | password |
32
| test3.cpp:17:28:17:36 | password1 | test3.cpp:22:15:22:23 | password1 |
43
| test3.cpp:17:51:17:59 | password2 | test3.cpp:26:15:26:23 | password2 |
54
| test3.cpp:45:8:45:15 | password | test3.cpp:47:15:47:22 | password |
@@ -91,8 +90,6 @@ edges
9190
| test.cpp:66:23:66:43 | cleartext password! | test.cpp:76:21:76:27 | call to encrypt |
9291
| test.cpp:66:23:66:43 | cleartext password! | test.cpp:76:29:76:39 | thePassword |
9392
nodes
94-
| test2.cpp:101:8:101:15 | password | semmle.label | password |
95-
| test2.cpp:103:8:103:15 | password | semmle.label | password |
9693
| test3.cpp:17:28:17:36 | password1 | semmle.label | password1 |
9794
| test3.cpp:17:51:17:59 | password2 | semmle.label | password2 |
9895
| test3.cpp:22:15:22:23 | password1 | semmle.label | password1 |
@@ -213,7 +210,6 @@ subpaths
213210
| test3.cpp:316:11:316:19 | password1 | test3.cpp:283:20:283:23 | data | test3.cpp:283:20:283:23 | data | test3.cpp:316:11:316:19 | ref arg password1 |
214211
| test3.cpp:324:11:324:14 | data | test3.cpp:293:20:293:23 | data | test3.cpp:293:20:293:23 | data | test3.cpp:324:11:324:14 | ref arg data |
215212
#select
216-
| test2.cpp:103:3:103:6 | call to gets | test2.cpp:101:8:101:15 | password | test2.cpp:103:8:103:15 | password | This operation receives into 'password', which may put unencrypted sensitive data into $@ | test2.cpp:101:8:101:15 | password | password |
217213
| test3.cpp:22:3:22:6 | call to send | test3.cpp:17:28:17:36 | password1 | test3.cpp:22:15:22:23 | password1 | This operation transmits 'password1', which may contain unencrypted sensitive data from $@ | test3.cpp:17:28:17:36 | password1 | password1 |
218214
| test3.cpp:26:3:26:6 | call to send | test3.cpp:17:51:17:59 | password2 | test3.cpp:26:15:26:23 | password2 | This operation transmits 'password2', which may contain unencrypted sensitive data from $@ | test3.cpp:17:51:17:59 | password2 | password2 |
219215
| test3.cpp:47:3:47:6 | call to recv | test3.cpp:45:8:45:15 | password | test3.cpp:47:15:47:22 | password | This operation receives into 'password', which may put unencrypted sensitive data into $@ | test3.cpp:45:8:45:15 | password | password |

cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/test2.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,6 @@ void test_gets()
100100
{
101101
char password[1024];
102102

103-
gets(password); // BAD [but FALSE POSITIVE from cpp/cleartext-transmission]
103+
gets(password); // BAD
104104
}
105105
}

0 commit comments

Comments
 (0)