Merge pull request #3482 from MathiasVP/getlim-taint-source

C++: Add GetDelim as taint step
This commit is contained in:
Jonas Jensen
2020-05-15 15:54:29 +02:00
committed by GitHub
6 changed files with 67 additions and 0 deletions

View File

@@ -14,3 +14,4 @@ private import implementations.Strdup
private import implementations.Strftime
private import implementations.StdString
private import implementations.Swap
private import implementations.GetDelim

View File

@@ -0,0 +1,40 @@
import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.Alias
import semmle.code.cpp.models.interfaces.SideEffect
import semmle.code.cpp.models.interfaces.FlowSource
/**
* The standard functions `getdelim`, `getwdelim` and the glibc variant `__getdelim`.
*/
class GetDelimFunction extends TaintFunction, AliasFunction, SideEffectFunction, RemoteFlowFunction {
GetDelimFunction() { hasGlobalName(["getdelim", "getwdelim", "__getdelim"]) }
override predicate hasTaintFlow(FunctionInput i, FunctionOutput o) {
i.isParameter(3) and o.isParameterDeref(0)
}
override predicate parameterNeverEscapes(int index) { index = [0, 1, 3] }
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
override predicate parameterIsAlwaysReturned(int index) { none() }
override predicate hasOnlySpecificReadSideEffects() { any() }
override predicate hasOnlySpecificWriteSideEffects() { any() }
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
i = [0, 1] and
buffer = false and
mustWrite = false
}
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
i = 3 and buffer = false
}
override predicate hasRemoteFlowSource(FunctionOutput output, string description) {
output.isParameterDeref(0) and
description = "String read by " + this.getName()
}
}

View File

@@ -591,3 +591,13 @@
| taint.cpp:463:6:463:6 | 0 | taint.cpp:471:7:471:7 | y | |
| taint.cpp:468:7:468:7 | ref arg x | taint.cpp:470:7:470:7 | x | |
| taint.cpp:468:10:468:10 | ref arg y | taint.cpp:471:7:471:7 | y | |
| taint.cpp:480:26:480:32 | source1 | taint.cpp:483:28:483:34 | source1 | |
| taint.cpp:481:15:481:21 | 0 | taint.cpp:483:12:483:15 | line | |
| taint.cpp:481:15:481:21 | 0 | taint.cpp:485:7:485:10 | line | |
| taint.cpp:482:9:482:9 | n | taint.cpp:483:19:483:19 | n | |
| taint.cpp:483:11:483:15 | ref arg & ... | taint.cpp:483:12:483:15 | line [inner post update] | |
| taint.cpp:483:11:483:15 | ref arg & ... | taint.cpp:485:7:485:10 | line | |
| taint.cpp:483:12:483:15 | line | taint.cpp:483:11:483:15 | & ... | |
| taint.cpp:483:18:483:19 | ref arg & ... | taint.cpp:483:19:483:19 | n [inner post update] | |
| taint.cpp:483:19:483:19 | n | taint.cpp:483:18:483:19 | & ... | |
| taint.cpp:483:28:483:34 | source1 | taint.cpp:483:11:483:15 | ref arg & ... | TAINT |

View File

@@ -470,3 +470,17 @@ void test_swop() {
sink(x); // clean [FALSE POSITIVE]
sink(y); // tainted
}
// --- getdelim ---
struct FILE;
int getdelim(char ** lineptr, size_t * n, int delimiter, FILE *stream);
void test_getdelim(FILE* source1) {
char* line = nullptr;
size_t n;
getdelim(&line, &n, '\n', source1);
sink(line);
}

View File

@@ -67,3 +67,4 @@
| taint.cpp:465:7:465:7 | x | taint.cpp:462:6:462:11 | call to source |
| taint.cpp:470:7:470:7 | x | taint.cpp:462:6:462:11 | call to source |
| taint.cpp:471:7:471:7 | y | taint.cpp:462:6:462:11 | call to source |
| taint.cpp:485:7:485:10 | line | taint.cpp:480:26:480:32 | source1 |

View File

@@ -28,3 +28,4 @@
| taint.cpp:430:9:430:14 | member | taint.cpp:428:13:428:18 | call to source |
| taint.cpp:465:7:465:7 | x | taint.cpp:462:6:462:11 | call to source |
| taint.cpp:470:7:470:7 | x | taint.cpp:462:6:462:11 | call to source |
| taint.cpp:485:7:485:10 | line | taint.cpp:480:26:480:32 | source1 |