Skip to content

Commit 9c7674c

Browse files
committed
[analyzer] TaintPropagation checker strlen() should not propagate
strlen(..) call should not propagate taintedness, because it brings in many false positive findings. It is a common pattern to copy user provided input to another buffer. In these cases we always get warnings about tainted data used as the malloc parameter: buf = malloc(strlen(tainted_txt) + 1); // false warning This pattern can lead to a denial of service attack only, when the attacker can directly specify the size of the allocated area as an arbitrary large number (e.g. the value is converted from a user provided string). Later, we could reintroduce strlen() as a taint propagating function with the consideration not to emit warnings when the tainted value cannot be "arbitrarily large" (such as the size of an already allocated memory block).
1 parent 730e8f6 commit 9c7674c

File tree

4 files changed

+9
-28
lines changed

4 files changed

+9
-28
lines changed

clang/docs/analyzer/checkers.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2599,8 +2599,8 @@ Default propagations rules:
25992599
``memcpy``, ``memmem``, ``memmove``, ``mbtowc``, ``pread``, ``qsort``,
26002600
``qsort_r``, ``rawmemchr``, ``read``, ``recv``, ``recvfrom``, ``rindex``,
26012601
``strcasestr``, ``strchr``, ``strchrnul``, ``strcasecmp``, ``strcmp``,
2602-
``strcspn``, ``strlen``, ``strncasecmp``, ``strncmp``, ``strndup``,
2603-
``strndupa``, ``strnlen``, ``strpbrk``, ``strrchr``, ``strsep``, ``strspn``,
2602+
``strcspn``, ``strncasecmp``, ``strncmp``, ``strndup``,
2603+
``strndupa``, ``strpbrk``, ``strrchr``, ``strsep``, ``strspn``,
26042604
``strstr``, ``strtol``, ``strtoll``, ``strtoul``, ``strtoull``, ``tolower``,
26052605
``toupper``, ``ttyname``, ``ttyname_r``, ``wctomb``, ``wcwidth``
26062606

clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -694,8 +694,6 @@ void GenericTaintChecker::initTaintRules(CheckerContext &C) const {
694694
{{{"strpbrk"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
695695
{{{"strndup"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
696696
{{{"strndupa"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
697-
{{{"strlen"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
698-
{{{"strnlen"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
699697
{{{"strtol"}}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},
700698
{{{"strtoll"}}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},
701699
{{{"strtoul"}}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},

clang/test/Analysis/taint-diagnostic-visitor.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ int scanf(const char *restrict format, ...);
1010
int system(const char *command);
1111
char* getenv( const char* env_var );
1212
size_t strlen( const char* str );
13+
int atoi( const char* str );
1314
void *malloc(size_t size );
1415
void free( void *ptr );
1516
char *fgets(char *str, int n, FILE *stream);
@@ -54,11 +55,11 @@ void taintDiagnosticVLA(void) {
5455
// propagating through variables and expressions
5556
char *taintDiagnosticPropagation(){
5657
char *pathbuf;
57-
char *pathlist=getenv("PATH"); // expected-note {{Taint originated here}}
58+
char *size=getenv("SIZE"); // expected-note {{Taint originated here}}
5859
// expected-note@-1 {{Taint propagated to the return value}}
59-
if (pathlist){ // expected-note {{Assuming 'pathlist' is non-null}}
60+
if (size){ // expected-note {{Assuming 'size' is non-null}}
6061
// expected-note@-1 {{Taking true branch}}
61-
pathbuf=(char*) malloc(strlen(pathlist)+1); // expected-warning{{Untrusted data is used to specify the buffer size}}
62+
pathbuf=(char*) malloc(atoi(size)); // expected-warning{{Untrusted data is used to specify the buffer size}}
6263
// expected-note@-1{{Untrusted data is used to specify the buffer size}}
6364
// expected-note@-2 {{Taint propagated to the return value}}
6465
return pathbuf;
@@ -71,12 +72,12 @@ char *taintDiagnosticPropagation(){
7172
char *taintDiagnosticPropagation2(){
7273
char *pathbuf;
7374
char *user_env2=getenv("USER_ENV_VAR2");//unrelated taint source
74-
char *pathlist=getenv("PATH"); // expected-note {{Taint originated here}}
75+
char *size=getenv("SIZE"); // expected-note {{Taint originated here}}
7576
// expected-note@-1 {{Taint propagated to the return value}}
7677
char *user_env=getenv("USER_ENV_VAR");//unrelated taint source
77-
if (pathlist){ // expected-note {{Assuming 'pathlist' is non-null}}
78+
if (size){ // expected-note {{Assuming 'size' is non-null}}
7879
// expected-note@-1 {{Taking true branch}}
79-
pathbuf=(char*) malloc(strlen(pathlist)+1); // expected-warning{{Untrusted data is used to specify the buffer size}}
80+
pathbuf=(char*) malloc(atoi(size)+1); // expected-warning{{Untrusted data is used to specify the buffer size}}
8081
// expected-note@-1{{Untrusted data is used to specify the buffer size}}
8182
// expected-note@-2 {{Taint propagated to the return value}}
8283
return pathbuf;

clang/test/Analysis/taint-generic.c

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -915,24 +915,6 @@ void testStrndupa(size_t n) {
915915
clang_analyzer_isTainted_charp(result); // expected-warning {{YES}}
916916
}
917917

918-
size_t strlen(const char *s);
919-
void testStrlen() {
920-
char s[10];
921-
scanf("%9s", s);
922-
923-
size_t result = strlen(s);
924-
clang_analyzer_isTainted_int(result); // expected-warning {{YES}}
925-
}
926-
927-
size_t strnlen(const char *s, size_t maxlen);
928-
void testStrnlen(size_t maxlen) {
929-
char s[10];
930-
scanf("%9s", s);
931-
932-
size_t result = strnlen(s, maxlen);
933-
clang_analyzer_isTainted_int(result); // expected-warning {{YES}}
934-
}
935-
936918
long strtol(const char *restrict nptr, char **restrict endptr, int base);
937919
long long strtoll(const char *restrict nptr, char **restrict endptr, int base);
938920
unsigned long int strtoul(const char *nptr, char **endptr, int base);

0 commit comments

Comments
 (0)