Skip to content

Commit b08de6c

Browse files
authored
Merge pull request github#3482 from MathiasVP/getlim-taint-source
C++: Add GetDelim as taint step
2 parents 5787871 + 7502c6f commit b08de6c

File tree

6 files changed

+67
-0
lines changed

6 files changed

+67
-0
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
@@ -14,3 +14,4 @@ private import implementations.Strdup
1414
private import implementations.Strftime
1515
private import implementations.StdString
1616
private import implementations.Swap
17+
private import implementations.GetDelim
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import semmle.code.cpp.models.interfaces.Taint
2+
import semmle.code.cpp.models.interfaces.Alias
3+
import semmle.code.cpp.models.interfaces.SideEffect
4+
import semmle.code.cpp.models.interfaces.FlowSource
5+
6+
/**
7+
* The standard functions `getdelim`, `getwdelim` and the glibc variant `__getdelim`.
8+
*/
9+
class GetDelimFunction extends TaintFunction, AliasFunction, SideEffectFunction, RemoteFlowFunction {
10+
GetDelimFunction() { hasGlobalName(["getdelim", "getwdelim", "__getdelim"]) }
11+
12+
override predicate hasTaintFlow(FunctionInput i, FunctionOutput o) {
13+
i.isParameter(3) and o.isParameterDeref(0)
14+
}
15+
16+
override predicate parameterNeverEscapes(int index) { index = [0, 1, 3] }
17+
18+
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
19+
20+
override predicate parameterIsAlwaysReturned(int index) { none() }
21+
22+
override predicate hasOnlySpecificReadSideEffects() { any() }
23+
24+
override predicate hasOnlySpecificWriteSideEffects() { any() }
25+
26+
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
27+
i = [0, 1] and
28+
buffer = false and
29+
mustWrite = false
30+
}
31+
32+
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
33+
i = 3 and buffer = false
34+
}
35+
36+
override predicate hasRemoteFlowSource(FunctionOutput output, string description) {
37+
output.isParameterDeref(0) and
38+
description = "String read by " + this.getName()
39+
}
40+
}

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,3 +591,13 @@
591591
| taint.cpp:463:6:463:6 | 0 | taint.cpp:471:7:471:7 | y | |
592592
| taint.cpp:468:7:468:7 | ref arg x | taint.cpp:470:7:470:7 | x | |
593593
| taint.cpp:468:10:468:10 | ref arg y | taint.cpp:471:7:471:7 | y | |
594+
| taint.cpp:480:26:480:32 | source1 | taint.cpp:483:28:483:34 | source1 | |
595+
| taint.cpp:481:15:481:21 | 0 | taint.cpp:483:12:483:15 | line | |
596+
| taint.cpp:481:15:481:21 | 0 | taint.cpp:485:7:485:10 | line | |
597+
| taint.cpp:482:9:482:9 | n | taint.cpp:483:19:483:19 | n | |
598+
| taint.cpp:483:11:483:15 | ref arg & ... | taint.cpp:483:12:483:15 | line [inner post update] | |
599+
| taint.cpp:483:11:483:15 | ref arg & ... | taint.cpp:485:7:485:10 | line | |
600+
| taint.cpp:483:12:483:15 | line | taint.cpp:483:11:483:15 | & ... | |
601+
| taint.cpp:483:18:483:19 | ref arg & ... | taint.cpp:483:19:483:19 | n [inner post update] | |
602+
| taint.cpp:483:19:483:19 | n | taint.cpp:483:18:483:19 | & ... | |
603+
| taint.cpp:483:28:483:34 | source1 | taint.cpp:483:11:483:15 | ref arg & ... | TAINT |

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,3 +470,17 @@ void test_swop() {
470470
sink(x); // clean [FALSE POSITIVE]
471471
sink(y); // tainted
472472
}
473+
474+
// --- getdelim ---
475+
476+
struct FILE;
477+
478+
int getdelim(char ** lineptr, size_t * n, int delimiter, FILE *stream);
479+
480+
void test_getdelim(FILE* source1) {
481+
char* line = nullptr;
482+
size_t n;
483+
getdelim(&line, &n, '\n', source1);
484+
485+
sink(line);
486+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,4 @@
6767
| taint.cpp:465:7:465:7 | x | taint.cpp:462:6:462:11 | call to source |
6868
| taint.cpp:470:7:470:7 | x | taint.cpp:462:6:462:11 | call to source |
6969
| taint.cpp:471:7:471:7 | y | taint.cpp:462:6:462:11 | call to source |
70+
| taint.cpp:485:7:485:10 | line | taint.cpp:480:26:480:32 | source1 |

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,4 @@
2828
| taint.cpp:430:9:430:14 | member | taint.cpp:428:13:428:18 | call to source |
2929
| taint.cpp:465:7:465:7 | x | taint.cpp:462:6:462:11 | call to source |
3030
| taint.cpp:470:7:470:7 | x | taint.cpp:462:6:462:11 | call to source |
31+
| taint.cpp:485:7:485:10 | line | taint.cpp:480:26:480:32 | source1 |

0 commit comments

Comments
 (0)