mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
C++: Implement model for _strinc and related functions.
This commit is contained in:
@@ -17,6 +17,7 @@ private import implementations.Strdup
|
||||
private import implementations.Strftime
|
||||
private import implementations.Strtok
|
||||
private import implementations.Strset
|
||||
private import implementations.Strcrement
|
||||
private import implementations.StdContainer
|
||||
private import implementations.StdPair
|
||||
private import implementations.StdMap
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Provides implementation classes modeling `strinc`, `strdec` and their variants.
|
||||
* See `semmle.code.cpp.models.Models` for usage information.
|
||||
*/
|
||||
|
||||
import semmle.code.cpp.models.interfaces.ArrayFunction
|
||||
import semmle.code.cpp.models.interfaces.Taint
|
||||
import semmle.code.cpp.models.interfaces.SideEffect
|
||||
|
||||
/**
|
||||
* The function `_strinc`, `_strdec` and their variants.
|
||||
*/
|
||||
private class Strcrement extends ArrayFunction, TaintFunction, SideEffectFunction {
|
||||
Strcrement() {
|
||||
this.hasGlobalName([
|
||||
"_strinc", // _strinc(source, locale)
|
||||
"_wcsinc", // _strinc(source, locale)
|
||||
"_mbsinc", // _strinc(source)
|
||||
"_mbsinc_l", // _strinc(source, locale)
|
||||
"_strdec", // _strdec(start, source)
|
||||
"_wcsdec", // _wcsdec(start, source)
|
||||
"_mbsdec", // _mbsdec(start, source)
|
||||
"_mbsdec_l" // _mbsdec_l(start, source, locale)
|
||||
])
|
||||
}
|
||||
|
||||
override predicate hasArrayWithNullTerminator(int bufParam) {
|
||||
// Match all parameters that are not locales.
|
||||
this.getParameter(bufParam).getUnspecifiedType() instanceof PointerType
|
||||
}
|
||||
|
||||
override predicate hasArrayInput(int bufParam) { hasArrayWithNullTerminator(bufParam) }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
exists(int index | hasArrayInput(index) |
|
||||
input.isParameter(index) and output.isReturnValue()
|
||||
or
|
||||
input.isParameterDeref(index) and output.isReturnValueDeref()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate hasOnlySpecificReadSideEffects() { any() }
|
||||
|
||||
override predicate hasOnlySpecificWriteSideEffects() { any() }
|
||||
|
||||
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
|
||||
hasArrayInput(i) and buffer = true
|
||||
}
|
||||
}
|
||||
@@ -5970,6 +5970,68 @@
|
||||
| taint.cpp:572:37:572:41 | delim | taint.cpp:572:21:572:26 | call to strsep | TAINT |
|
||||
| taint.cpp:573:10:573:18 | ref arg tokenized | taint.cpp:574:11:574:19 | tokenized | |
|
||||
| taint.cpp:574:11:574:19 | tokenized | taint.cpp:574:10:574:19 | * ... | TAINT |
|
||||
| taint.cpp:584:25:584:30 | source | taint.cpp:585:18:585:23 | source | |
|
||||
| taint.cpp:584:39:584:43 | clean | taint.cpp:589:18:589:22 | clean | |
|
||||
| taint.cpp:584:82:584:87 | locale | taint.cpp:585:26:585:31 | locale | |
|
||||
| taint.cpp:584:82:584:87 | locale | taint.cpp:589:25:589:30 | locale | |
|
||||
| taint.cpp:585:10:585:16 | call to _strinc | taint.cpp:585:2:585:32 | ... = ... | |
|
||||
| taint.cpp:585:10:585:16 | call to _strinc | taint.cpp:586:7:586:11 | dest1 | |
|
||||
| taint.cpp:585:10:585:16 | call to _strinc | taint.cpp:587:8:587:12 | dest1 | |
|
||||
| taint.cpp:585:18:585:23 | source | taint.cpp:585:10:585:16 | call to _strinc | TAINT |
|
||||
| taint.cpp:585:26:585:31 | locale | taint.cpp:585:10:585:16 | call to _strinc | TAINT |
|
||||
| taint.cpp:585:26:585:31 | ref arg locale | taint.cpp:589:25:589:30 | locale | |
|
||||
| taint.cpp:586:7:586:11 | ref arg dest1 | taint.cpp:587:8:587:12 | dest1 | |
|
||||
| taint.cpp:587:8:587:12 | dest1 | taint.cpp:587:7:587:12 | * ... | TAINT |
|
||||
| taint.cpp:589:10:589:16 | call to _strinc | taint.cpp:589:2:589:31 | ... = ... | |
|
||||
| taint.cpp:589:10:589:16 | call to _strinc | taint.cpp:590:7:590:11 | dest2 | |
|
||||
| taint.cpp:589:10:589:16 | call to _strinc | taint.cpp:591:8:591:12 | dest2 | |
|
||||
| taint.cpp:589:18:589:22 | clean | taint.cpp:589:10:589:16 | call to _strinc | TAINT |
|
||||
| taint.cpp:589:25:589:30 | locale | taint.cpp:589:10:589:16 | call to _strinc | TAINT |
|
||||
| taint.cpp:590:7:590:11 | ref arg dest2 | taint.cpp:591:8:591:12 | dest2 | |
|
||||
| taint.cpp:591:8:591:12 | dest2 | taint.cpp:591:7:591:12 | * ... | TAINT |
|
||||
| taint.cpp:594:34:594:48 | source_unsigned | taint.cpp:595:26:595:40 | source_unsigned | |
|
||||
| taint.cpp:594:57:594:62 | source | taint.cpp:599:40:599:45 | source | |
|
||||
| taint.cpp:595:18:595:24 | call to _mbsinc | taint.cpp:595:2:595:41 | ... = ... | |
|
||||
| taint.cpp:595:18:595:24 | call to _mbsinc | taint.cpp:596:7:596:19 | dest_unsigned | |
|
||||
| taint.cpp:595:18:595:24 | call to _mbsinc | taint.cpp:597:8:597:20 | dest_unsigned | |
|
||||
| taint.cpp:595:26:595:40 | source_unsigned | taint.cpp:595:18:595:24 | call to _mbsinc | TAINT |
|
||||
| taint.cpp:596:7:596:19 | ref arg dest_unsigned | taint.cpp:597:8:597:20 | dest_unsigned | |
|
||||
| taint.cpp:597:8:597:20 | dest_unsigned | taint.cpp:597:7:597:20 | * ... | TAINT |
|
||||
| taint.cpp:599:16:599:22 | call to _mbsinc | taint.cpp:599:2:599:46 | ... = ... | |
|
||||
| taint.cpp:599:16:599:22 | call to _mbsinc | taint.cpp:600:7:600:10 | dest | |
|
||||
| taint.cpp:599:16:599:22 | call to _mbsinc | taint.cpp:601:8:601:11 | dest | |
|
||||
| taint.cpp:599:40:599:45 | source | taint.cpp:599:16:599:22 | call to _mbsinc | TAINT |
|
||||
| taint.cpp:600:7:600:10 | ref arg dest | taint.cpp:601:8:601:11 | dest | |
|
||||
| taint.cpp:601:8:601:11 | dest | taint.cpp:601:7:601:11 | * ... | TAINT |
|
||||
| taint.cpp:604:40:604:45 | source | taint.cpp:605:18:605:23 | source | |
|
||||
| taint.cpp:604:40:604:45 | source | taint.cpp:605:31:605:36 | source | |
|
||||
| taint.cpp:604:40:604:45 | source | taint.cpp:611:25:611:30 | source | |
|
||||
| taint.cpp:604:40:604:45 | source | taint.cpp:616:18:616:23 | source | |
|
||||
| taint.cpp:604:63:604:67 | clean | taint.cpp:611:18:611:22 | clean | |
|
||||
| taint.cpp:604:63:604:67 | clean | taint.cpp:616:26:616:30 | clean | |
|
||||
| taint.cpp:605:10:605:16 | call to _strdec | taint.cpp:605:2:605:37 | ... = ... | |
|
||||
| taint.cpp:605:10:605:16 | call to _strdec | taint.cpp:606:7:606:11 | dest1 | |
|
||||
| taint.cpp:605:10:605:16 | call to _strdec | taint.cpp:607:8:607:12 | dest1 | |
|
||||
| taint.cpp:605:18:605:23 | source | taint.cpp:605:18:605:28 | ... + ... | TAINT |
|
||||
| taint.cpp:605:18:605:28 | ... + ... | taint.cpp:605:10:605:16 | call to _strdec | TAINT |
|
||||
| taint.cpp:605:27:605:28 | 12 | taint.cpp:605:18:605:28 | ... + ... | TAINT |
|
||||
| taint.cpp:605:31:605:36 | source | taint.cpp:605:10:605:16 | call to _strdec | TAINT |
|
||||
| taint.cpp:606:7:606:11 | ref arg dest1 | taint.cpp:607:8:607:12 | dest1 | |
|
||||
| taint.cpp:607:8:607:12 | dest1 | taint.cpp:607:7:607:12 | * ... | TAINT |
|
||||
| taint.cpp:611:10:611:16 | call to _strdec | taint.cpp:611:2:611:31 | ... = ... | |
|
||||
| taint.cpp:611:10:611:16 | call to _strdec | taint.cpp:612:7:612:11 | dest2 | |
|
||||
| taint.cpp:611:10:611:16 | call to _strdec | taint.cpp:613:8:613:12 | dest2 | |
|
||||
| taint.cpp:611:18:611:22 | clean | taint.cpp:611:10:611:16 | call to _strdec | TAINT |
|
||||
| taint.cpp:611:25:611:30 | source | taint.cpp:611:10:611:16 | call to _strdec | TAINT |
|
||||
| taint.cpp:612:7:612:11 | ref arg dest2 | taint.cpp:613:8:613:12 | dest2 | |
|
||||
| taint.cpp:613:8:613:12 | dest2 | taint.cpp:613:7:613:12 | * ... | TAINT |
|
||||
| taint.cpp:616:10:616:16 | call to _strdec | taint.cpp:616:2:616:31 | ... = ... | |
|
||||
| taint.cpp:616:10:616:16 | call to _strdec | taint.cpp:617:7:617:11 | dest3 | |
|
||||
| taint.cpp:616:10:616:16 | call to _strdec | taint.cpp:618:8:618:12 | dest3 | |
|
||||
| taint.cpp:616:18:616:23 | source | taint.cpp:616:10:616:16 | call to _strdec | TAINT |
|
||||
| taint.cpp:616:26:616:30 | clean | taint.cpp:616:10:616:16 | call to _strdec | TAINT |
|
||||
| taint.cpp:617:7:617:11 | ref arg dest3 | taint.cpp:618:8:618:12 | dest3 | |
|
||||
| taint.cpp:618:8:618:12 | dest3 | taint.cpp:618:7:618:12 | * ... | TAINT |
|
||||
| vector.cpp:16:43:16:49 | source1 | vector.cpp:17:26:17:32 | source1 | |
|
||||
| vector.cpp:16:43:16:49 | source1 | vector.cpp:31:38:31:44 | source1 | |
|
||||
| vector.cpp:17:21:17:33 | call to vector | vector.cpp:19:14:19:14 | v | |
|
||||
|
||||
@@ -574,3 +574,46 @@ void test_strsep(char *source) {
|
||||
sink(*tokenized); // $ ast,ir
|
||||
}
|
||||
}
|
||||
|
||||
// --- _strinc and related functions ---
|
||||
|
||||
char* _strinc(const char*, _locale_t);
|
||||
unsigned char* _mbsinc(const unsigned char*);
|
||||
unsigned char *_strdec(const unsigned char*, const unsigned char*);
|
||||
|
||||
void test__strinc(char* source, char* clean, char* dest1, char* dest2, _locale_t locale) {
|
||||
dest1 = _strinc(source, locale);
|
||||
sink(dest1); // $ ast,ir
|
||||
sink(*dest1); // $ ast,ir
|
||||
|
||||
dest2 = _strinc(clean, locale);
|
||||
sink(dest2);
|
||||
sink(*dest2);
|
||||
}
|
||||
|
||||
void test__mbsinc(unsigned char* source_unsigned, char* source, unsigned char* dest_unsigned, char* dest) {
|
||||
dest_unsigned = _mbsinc(source_unsigned);
|
||||
sink(dest_unsigned); // $ ast,ir
|
||||
sink(*dest_unsigned); // $ ast,ir
|
||||
|
||||
dest = (char*)_mbsinc((unsigned char*)source);
|
||||
sink(dest); // $ ast,ir
|
||||
sink(*dest); // $ ast,ir
|
||||
}
|
||||
|
||||
void test__strdec(const unsigned char* source, unsigned char* clean, unsigned char* dest1, unsigned char* dest2, unsigned char* dest3) {
|
||||
dest1 = _strdec(source + 12, source);
|
||||
sink(dest1); // $ ast,ir
|
||||
sink(*dest1); // $ ast,ir
|
||||
|
||||
// If `clean` does not precede `source` this technically breaks the precondition of _strdec.
|
||||
// We would still like to have taint, though.
|
||||
dest2 = _strdec(clean, source);
|
||||
sink(dest2); // $ ast,ir
|
||||
sink(*dest2); // $ ast,ir
|
||||
|
||||
// Also breaks the precondition on _strdec.
|
||||
dest3 = _strdec(source, clean);
|
||||
sink(dest3); // $ ast,ir
|
||||
sink(*dest3); // $ ast,ir
|
||||
}
|
||||
Reference in New Issue
Block a user