Skip to content

Commit 6e71c68

Browse files
committed
C++: Add strsep model implementation.
1 parent 749dfe4 commit 6e71c68

File tree

3 files changed

+66
-0
lines changed

3 files changed

+66
-0
lines changed

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

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,42 @@ private class Strtok extends ArrayFunction, AliasFunction, TaintFunction, SideEf
4747
i = [0, 1] and buffer = true
4848
}
4949
}
50+
51+
/**
52+
* The function `strtok` is a variant of `strtok` that takes a `char**` parameter instead of
53+
* a `char*` as the first parameter.
54+
*/
55+
private class Strsep extends ArrayFunction, AliasFunction, TaintFunction, SideEffectFunction {
56+
Strsep() { this.hasGlobalName("strsep") }
57+
58+
override predicate hasArrayWithNullTerminator(int bufParam) { bufParam = 1 }
59+
60+
override predicate hasArrayInput(int bufParam) { bufParam = 1 }
61+
62+
override predicate parameterNeverEscapes(int index) { index = [0, 1] }
63+
64+
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
65+
66+
override predicate parameterIsAlwaysReturned(int index) { none() }
67+
68+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
69+
// NOTE: What we really want here is: (input.isParameterDerefDeref(0) or input.isParameterDeref(1))
70+
// as the first conjunct.
71+
input.isParameterDeref([0, 1]) and
72+
(output.isReturnValue() or output.isReturnValueDeref())
73+
}
74+
75+
override predicate hasOnlySpecificReadSideEffects() { any() }
76+
77+
override predicate hasOnlySpecificWriteSideEffects() { any() }
78+
79+
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
80+
i = 0 and buffer = false and mustWrite = false
81+
}
82+
83+
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
84+
i = 0 and buffer = false
85+
or
86+
i = 1 and buffer = true
87+
}
88+
}

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5952,6 +5952,20 @@
59525952
| taint.cpp:560:8:560:12 | dest3 | taint.cpp:560:7:560:12 | * ... | TAINT |
59535953
| taint.cpp:561:7:561:11 | ref arg dest4 | taint.cpp:562:8:562:12 | dest4 | |
59545954
| taint.cpp:562:8:562:12 | dest4 | taint.cpp:562:7:562:12 | * ... | TAINT |
5955+
| taint.cpp:569:24:569:29 | source | taint.cpp:572:29:572:34 | source | |
5956+
| taint.cpp:570:23:570:30 | ,.-;:_ | taint.cpp:572:37:572:41 | delim | |
5957+
| taint.cpp:572:9:572:17 | tokenized | taint.cpp:572:9:572:42 | ... = ... | |
5958+
| taint.cpp:572:21:572:26 | call to strsep | taint.cpp:572:9:572:42 | ... = ... | |
5959+
| taint.cpp:572:21:572:26 | call to strsep | taint.cpp:573:10:573:18 | tokenized | |
5960+
| taint.cpp:572:21:572:26 | call to strsep | taint.cpp:574:11:574:19 | tokenized | |
5961+
| taint.cpp:572:28:572:34 | & ... | taint.cpp:572:21:572:26 | call to strsep | TAINT |
5962+
| taint.cpp:572:28:572:34 | ref arg & ... | taint.cpp:572:29:572:34 | source | |
5963+
| taint.cpp:572:28:572:34 | ref arg & ... | taint.cpp:572:29:572:34 | source [inner post update] | |
5964+
| taint.cpp:572:29:572:34 | source | taint.cpp:572:21:572:26 | call to strsep | TAINT |
5965+
| taint.cpp:572:29:572:34 | source | taint.cpp:572:28:572:34 | & ... | |
5966+
| taint.cpp:572:37:572:41 | delim | taint.cpp:572:21:572:26 | call to strsep | TAINT |
5967+
| taint.cpp:573:10:573:18 | ref arg tokenized | taint.cpp:574:11:574:19 | tokenized | |
5968+
| taint.cpp:574:11:574:19 | tokenized | taint.cpp:574:10:574:19 | * ... | TAINT |
59555969
| vector.cpp:16:43:16:49 | source1 | vector.cpp:17:26:17:32 | source1 | |
59565970
| vector.cpp:16:43:16:49 | source1 | vector.cpp:31:38:31:44 | source1 | |
59575971
| vector.cpp:17:21:17:33 | call to vector | vector.cpp:19:14:19:14 | v | |

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,3 +561,16 @@ void test__mbsncat_l(unsigned char* dest1, unsigned const char* ptr, unsigned ch
561561
sink(dest4);
562562
sink(*dest4);
563563
}
564+
565+
// --- strsep ---
566+
567+
char *strsep(char**, const char *);
568+
569+
void test_strsep(char *source) {
570+
const char* delim = ",.-;:_";
571+
char* tokenized;
572+
while(tokenized = strsep(&source, delim)) {
573+
sink(tokenized); // $ ast,ir
574+
sink(*tokenized); // $ ast,ir
575+
}
576+
}

0 commit comments

Comments
 (0)