1 // RUN: %clang_analyze_cc1 -Wno-format-security -Wno-pointer-to-int-cast \
2 // RUN: -Wno-incompatible-library-redeclaration -verify %s \
3 // RUN: -analyzer-checker=alpha.security.taint \
4 // RUN: -analyzer-checker=core \
5 // RUN: -analyzer-checker=alpha.security.ArrayBoundV2 \
6 // RUN: -analyzer-checker=debug.ExprInspection \
7 // RUN: -analyzer-config \
8 // RUN: alpha.security.taint.TaintPropagation:Config=%S/Inputs/taint-generic-config.yaml
10 // RUN: %clang_analyze_cc1 -Wno-format-security -Wno-pointer-to-int-cast \
11 // RUN: -Wno-incompatible-library-redeclaration -verify %s \
12 // RUN: -DFILE_IS_STRUCT \
13 // RUN: -analyzer-checker=alpha.security.taint \
14 // RUN: -analyzer-checker=core \
15 // RUN: -analyzer-checker=alpha.security.ArrayBoundV2 \
16 // RUN: -analyzer-checker=debug.ExprInspection \
17 // RUN: -analyzer-config \
18 // RUN: alpha.security.taint.TaintPropagation:Config=%S/Inputs/taint-generic-config.yaml
20 // RUN: not %clang_analyze_cc1 -Wno-pointer-to-int-cast \
21 // RUN: -Wno-incompatible-library-redeclaration -verify %s \
22 // RUN: -analyzer-checker=alpha.security.taint \
23 // RUN: -analyzer-checker=debug.ExprInspection \
24 // RUN: -analyzer-config \
25 // RUN: alpha.security.taint.TaintPropagation:Config=justguessit \
26 // RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-INVALID-FILE
28 // CHECK-INVALID-FILE: (frontend): invalid input for checker option
29 // CHECK-INVALID-FILE-SAME: 'alpha.security.taint.TaintPropagation:Config',
30 // CHECK-INVALID-FILE-SAME: that expects a valid filename instead of
31 // CHECK-INVALID-FILE-SAME: 'justguessit'
33 // RUN: not %clang_analyze_cc1 -Wno-incompatible-library-redeclaration \
35 // RUN: -analyzer-checker=alpha.security.taint \
36 // RUN: -analyzer-checker=debug.ExprInspection \
37 // RUN: -analyzer-config \
38 // RUN: alpha.security.taint.TaintPropagation:Config=%S/Inputs/taint-generic-config-ill-formed.yaml \
39 // RUN: 2>&1 | FileCheck -DMSG=%errc_EINVAL %s -check-prefix=CHECK-ILL-FORMED
41 // CHECK-ILL-FORMED: (frontend): invalid input for checker option
42 // CHECK-ILL-FORMED-SAME: 'alpha.security.taint.TaintPropagation:Config',
43 // CHECK-ILL-FORMED-SAME: that expects a valid yaml file: [[MSG]]
45 // RUN: not %clang_analyze_cc1 -Wno-incompatible-library-redeclaration \
47 // RUN: -analyzer-checker=alpha.security.taint \
48 // RUN: -analyzer-checker=debug.ExprInspection \
49 // RUN: -analyzer-config \
50 // RUN: alpha.security.taint.TaintPropagation:Config=%S/Inputs/taint-generic-config-invalid-arg.yaml \
51 // RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-INVALID-ARG
53 // CHECK-INVALID-ARG: (frontend): invalid input for checker option
54 // CHECK-INVALID-ARG-SAME: 'alpha.security.taint.TaintPropagation:Config',
55 // CHECK-INVALID-ARG-SAME: that expects an argument number for propagation
56 // CHECK-INVALID-ARG-SAME: rules greater or equal to -1
58 typedef long long rsize_t
;
59 void clang_analyzer_isTainted_char(char);
60 void clang_analyzer_isTainted_charp(char*);
61 void clang_analyzer_isTainted_int(int);
63 int scanf(const char *restrict format
, ...);
64 char *gets(char *str
);
65 char *gets_s(char *str
, rsize_t n
);
68 typedef struct _FILE
FILE;
70 extern struct _FILE
*stdin
;
78 char *getenv(const char *name
);
80 FILE *fopen(const char *name
, const char *mode
);
82 int fscanf(FILE *restrict stream
, const char *restrict format
, ...);
83 int sprintf(char *str
, const char *format
, ...);
84 void setproctitle(const char *fmt
, ...);
85 void setproctitle_init(int argc
, char *argv
[], char *envp
[]);
86 typedef __typeof(sizeof(int)) size_t;
87 typedef signed long long ssize_t
;
89 // Define string functions. Use builtin for some of them. They all default to
90 // the processing in the taint checker.
91 #define strcpy(dest, src) \
92 ((__builtin_object_size(dest, 0) != -1ULL) \
93 ? __builtin___strcpy_chk (dest, src, __builtin_object_size(dest, 1)) \
94 : __inline_strcpy_chk(dest, src))
96 static char *__inline_strcpy_chk (char *dest
, const char *src
) {
97 return __builtin___strcpy_chk(dest
, src
, __builtin_object_size(dest
, 1));
99 char *stpcpy(char *restrict s1
, const char *restrict s2
);
100 char *strncpy( char * destination
, const char * source
, size_t num
);
101 char *strndup(const char *s
, size_t n
);
102 char *strncat(char *restrict s1
, const char *restrict s2
, size_t n
);
104 void *malloc(size_t);
105 void *calloc(size_t nmemb
, size_t size
);
106 void bcopy(void *s1
, void *s2
, size_t n
);
108 typedef size_t socklen_t
;
111 unsigned short sa_family
;
118 void bufferScanfDirect(void)
122 Buffer
[n
] = 1; // expected-warning {{Out of bound memory access }}
125 void bufferScanfArithmetic1(int x
) {
129 Buffer
[m
] = 1; // expected-warning {{Out of bound memory access }}
132 void bufferScanfArithmetic2(int x
) {
135 int m
= 100 - (n
+ 3) * x
;
136 Buffer
[m
] = 1; // expected-warning {{Out of bound memory access }}
139 void bufferScanfAssignment(int x
) {
145 Buffer
[m
] = 1; // expected-warning {{Out of bound memory access }}
149 void scanfArg(void) {
151 scanf("%d", t
); // expected-warning {{format specifies type 'int *' but the argument has type 'int'}}
154 void bufferGetchar(int x
) {
156 Buffer
[m
] = 1; //expected-warning {{Out of bound memory access (index is tainted)}}
159 void testUncontrolledFormatString(char **p
) {
161 fscanf(stdin
, "%s", s
);
163 sprintf(buf
,s
); // expected-warning {{Uncontrolled Format String}}
164 setproctitle(s
, 3); // expected-warning {{Uncontrolled Format String}}
166 // Test taint propagation through strcpy and family.
169 sprintf(buf
,scpy
); // expected-warning {{Uncontrolled Format String}}
171 stpcpy(*(++p
), s
); // this generates __inline.
172 setproctitle(*(p
), 3); // expected-warning {{Uncontrolled Format String}}
176 setproctitle(spcpy
, 3); // expected-warning {{Uncontrolled Format String}}
179 spcpyret
= stpcpy(spcpy
, s
);
180 setproctitle(spcpyret
, 3); // expected-warning {{Uncontrolled Format String}}
183 strncpy(sncpy
, s
, 20);
184 setproctitle(sncpy
, 3); // expected-warning {{Uncontrolled Format String}}
187 dup
= strndup(s
, 20);
188 setproctitle(dup
, 3); // expected-warning {{Uncontrolled Format String}}
192 int system(const char *command
);
193 void testTaintSystemCall(void) {
197 system(addr
); // expected-warning {{Untrusted data is passed to a system call}}
199 // Test that spintf transfers taint.
200 sprintf(buffer
, "/bin/mail %s < /tmp/email", addr
);
201 system(buffer
); // expected-warning {{Untrusted data is passed to a system call}}
204 void testTaintSystemCall2(void) {
205 // Test that snpintf transfers taint.
209 __builtin_snprintf(buffern
, 10, "/bin/mail %s < /tmp/email", addr
);
210 system(buffern
); // expected-warning {{Untrusted data is passed to a system call}}
213 void testTaintSystemCall3(void) {
217 scanf("%s %d", addr
, &numt
);
218 __builtin_snprintf(buffern2
, numt
, "/bin/mail %s < /tmp/email", "abcd");
219 system(buffern2
); // expected-warning {{Untrusted data is passed to a system call}}
222 void testGets(void) {
225 system(str
); // expected-warning {{Untrusted data is passed to a system call}}
228 void testGets_s(void) {
231 system(str
); // expected-warning {{Untrusted data is passed to a system call}}
234 void testTaintedBufferSize(void) {
238 int *buf1
= (int*)malloc(ts
*sizeof(int)); // expected-warning {{Untrusted data is used to specify the buffer size}}
239 char *dst
= (char*)calloc(ts
, sizeof(char)); //expected-warning {{Untrusted data is used to specify the buffer size}}
240 bcopy(buf1
, dst
, ts
); // expected-warning {{Untrusted data is used to specify the buffer size}}
241 __builtin_memcpy(dst
, buf1
, (ts
+ 4)*sizeof(char)); // expected-warning {{Untrusted data is used to specify the buffer size}}
243 // If both buffers are trusted, do not issue a warning.
244 char *dst2
= (char*)malloc(ts
*sizeof(char)); // expected-warning {{Untrusted data is used to specify the buffer size}}
245 strncat(dst2
, dst
, ts
); // no-warning
248 #define AF_UNIX 1 /* local to host (pipes) */
249 #define AF_INET 2 /* internetwork: UDP, TCP, etc. */
250 #define AF_LOCAL AF_UNIX /* backward compatibility */
251 #define SOCK_STREAM 1
252 int socket(int, int, int);
253 size_t read(int, void *, size_t);
254 int execl(const char *, const char *, ...);
256 void testSocket(void) {
260 sock
= socket(AF_INET
, SOCK_STREAM
, 0);
261 read(sock
, buffer
, 100);
262 execl(buffer
, "filename", 0); // expected-warning {{Untrusted data is passed to a system call}}
264 sock
= socket(AF_LOCAL
, SOCK_STREAM
, 0);
265 read(sock
, buffer
, 100);
266 execl(buffer
, "filename", 0); // no-warning
268 sock
= socket(AF_INET
, SOCK_STREAM
, 0);
269 // References to both buffer and &buffer as an argument should taint the argument
270 read(sock
, &buffer
, 100);
271 execl(buffer
, "filename", 0); // expected-warning {{Untrusted data is passed to a system call}}
274 void testStruct(void) {
283 sock
= socket(AF_INET
, SOCK_STREAM
, 0);
284 read(sock
, &tainted
, sizeof(tainted
));
285 __builtin_memcpy(buffer
, tainted
.buf
, tainted
.length
); // expected-warning {{Untrusted data is used to specify the buffer size}}
288 void testStructArray(void) {
293 char dstbuf
[16], srcbuf
[16];
296 sock
= socket(AF_INET
, SOCK_STREAM
, 0);
297 __builtin_memset(srcbuf
, 0, sizeof(srcbuf
));
299 read(sock
, &tainted
[0], sizeof(tainted
));
300 __builtin_memcpy(dstbuf
, srcbuf
, tainted
[0].length
); // expected-warning {{Untrusted data is used to specify the buffer size}}
302 __builtin_memset(&tainted
, 0, sizeof(tainted
));
303 read(sock
, &tainted
, sizeof(tainted
));
304 __builtin_memcpy(dstbuf
, srcbuf
, tainted
[0].length
); // expected-warning {{Untrusted data is used to specify the buffer size}}
306 __builtin_memset(&tainted
, 0, sizeof(tainted
));
307 // If we taint element 1, we should not raise an alert on taint for element 0 or element 2
308 read(sock
, &tainted
[1], sizeof(tainted
));
309 __builtin_memcpy(dstbuf
, srcbuf
, tainted
[0].length
); // no-warning
310 __builtin_memcpy(dstbuf
, srcbuf
, tainted
[2].length
); // no-warning
313 void testUnion(void) {
321 int sock
= socket(AF_INET
, SOCK_STREAM
, 0);
322 read(sock
, &tainted
.y
, sizeof(tainted
.y
));
323 // FIXME: overlapping regions aren't detected by isTainted yet
324 __builtin_memcpy(buffer
, tainted
.y
, tainted
.x
);
327 int testDivByZero(void) {
330 return 5/x
; // expected-warning {{Division by a tainted value, possibly zero}}
334 void testTaintedVLASize(void) {
337 int vla
[x
]; // expected-warning{{Declared variable-length array (VLA) has tainted size}}
340 // This computation used to take a very long time.
341 #define longcmp(a,b,c) { \
342 a -= c; a ^= c; c += b; b -= a; b ^= (a<<6) | (a >> (32-b)); a += c; c -= b; c ^= b; b += a; \
343 a -= c; a ^= c; c += b; b -= a; b ^= a; a += c; c -= b; c ^= b; b += a; }
345 unsigned radar11369570_hanging(const unsigned char *arr
, int l
) {
347 a
= b
= c
= 0x9899e3 + l
;
353 a
+= (arr
[3] + ((unsigned) arr
[2] << 8) + ((unsigned) arr
[1] << 16) + ((unsigned) arr
[0] << 24));
357 return 5/a
; // expected-warning {{Division by a tainted value, possibly zero}}
360 // Check that we do not assert of the following code.
361 int SymSymExprWithDiffTypes(void* p
) {
364 int j
= (i
% (int)(long)p
);
365 return 5/j
; // expected-warning {{Division by a tainted value, possibly zero}}
369 void constraintManagerShouldTreatAsOpaque(int rhs
) {
372 // This comparison used to hit an assertion in the constraint manager,
373 // which didn't handle NonLoc sym-sym comparisons.
377 *(volatile int *) 0; // no-warning
380 int testSprintf_is_not_a_source(char *buf
, char *msg
) {
381 int x
= sprintf(buf
, "%s", msg
); // no-warning
382 return 1 / x
; // no-warning: 'sprintf' is not a taint source
385 int testSprintf_propagates_taint(char *buf
, char *msg
) {
387 int x
= sprintf(buf
, "%s", msg
); // propagate taint!
388 return 1 / x
; // expected-warning {{Division by a tainted value, possibly zero}}
391 int scanf_s(const char *format
, ...);
392 int testScanf_s_(int *out
) {
394 return 1 / *out
; // expected-warning {{Division by a tainted value, possibly zero}}
397 #define _IO_FILE FILE
398 int _IO_getc(_IO_FILE
*__fp
);
399 int testUnderscoreIO_getc(_IO_FILE
*fp
) {
400 char c
= _IO_getc(fp
);
401 return 1 / c
; // expected-warning {{Division by a tainted value, possibly zero}}
404 char *getcwd(char *buf
, size_t size
);
405 int testGetcwd(char *buf
, size_t size
) {
406 char *c
= getcwd(buf
, size
);
407 return system(c
); // expected-warning {{Untrusted data is passed to a system call}}
410 char *getwd(char *buf
);
411 int testGetwd(char *buf
) {
412 char *c
= getwd(buf
);
413 return system(c
); // expected-warning {{Untrusted data is passed to a system call}}
416 ssize_t
readlink(const char *path
, char *buf
, size_t bufsiz
);
417 int testReadlink(char *path
, char *buf
, size_t bufsiz
) {
418 ssize_t s
= readlink(path
, buf
, bufsiz
);
419 system(buf
); // expected-warning {{Untrusted data is passed to a system call}}
420 // readlink never returns 0
421 return 1 / (s
+ 1); // expected-warning {{Division by a tainted value, possibly zero}}
424 ssize_t
readlinkat(int dirfd
, const char *pathname
, char *buf
, size_t bufsiz
);
425 int testReadlinkat(int dirfd
, char *path
, char *buf
, size_t bufsiz
) {
426 ssize_t s
= readlinkat(dirfd
, path
, buf
, bufsiz
);
427 system(buf
); // expected-warning {{Untrusted data is passed to a system call}}
428 (void)(1 / dirfd
); // arg 0 is not tainted
429 system(path
); // arg 1 is not tainted
430 (void)(1 / bufsiz
); // arg 3 is not tainted
431 // readlinkat never returns 0
432 return 1 / (s
+ 1); // expected-warning {{Division by a tainted value, possibly zero}}
435 char *get_current_dir_name(void);
436 int testGet_current_dir_name() {
437 char *d
= get_current_dir_name();
438 return system(d
); // expected-warning {{Untrusted data is passed to a system call}}
441 int gethostname(char *name
, size_t len
);
442 int testGethostname(char *name
, size_t len
) {
443 gethostname(name
, len
);
444 return system(name
); // expected-warning {{Untrusted data is passed to a system call}}
447 int getnameinfo(const struct sockaddr
*restrict addr
, socklen_t addrlen
,
448 char *restrict host
, socklen_t hostlen
,
449 char *restrict serv
, socklen_t servlen
, int flags
);
450 int testGetnameinfo(const struct sockaddr
*restrict addr
, socklen_t addrlen
,
451 char *restrict host
, socklen_t hostlen
,
452 char *restrict serv
, socklen_t servlen
, int flags
) {
453 getnameinfo(addr
, addrlen
, host
, hostlen
, serv
, servlen
, flags
);
455 system(host
); // expected-warning {{Untrusted data is passed to a system call}}
456 return system(serv
); // expected-warning {{Untrusted data is passed to a system call}}
459 int getseuserbyname(const char *linuxuser
, char **selinuxuser
, char **level
);
460 int testGetseuserbyname(const char *linuxuser
, char **selinuxuser
, char **level
) {
461 getseuserbyname(linuxuser
, selinuxuser
, level
);
462 system(selinuxuser
[0]); // expected-warning {{Untrusted data is passed to a system call}}
463 return system(level
[0]); // expected-warning {{Untrusted data is passed to a system call}}
467 int getgroups(int size
, gid_t list
[]);
468 int testGetgroups(int size
, gid_t list
[], bool flag
) {
469 int result
= getgroups(size
, list
);
471 return 1 / list
[0]; // expected-warning {{Division by a tainted value, possibly zero}}
473 return 1 / (result
+ 1); // expected-warning {{Division by a tainted value, possibly zero}}
476 char *getlogin(void);
478 char *n
= getlogin();
479 return system(n
); // expected-warning {{Untrusted data is passed to a system call}}
482 int getlogin_r(char *buf
, size_t bufsize
);
483 int testGetlogin_r(char *buf
, size_t bufsize
) {
484 getlogin_r(buf
, bufsize
);
485 return system(buf
); // expected-warning {{Untrusted data is passed to a system call}}
488 int fscanf_s(FILE *stream
, const char *format
, ...);
489 void testFscanf_s(const char *fname
, int *d
) {
490 FILE *f
= fopen(fname
, "r");
491 fscanf_s(f
, "%d", d
);
492 clang_analyzer_isTainted_int(*d
); // expected-warning {{YES}}
495 int fread(void *buffer
, size_t size
, size_t count
, FILE *stream
);
496 void testFread(const char *fname
, int *buffer
, size_t size
, size_t count
) {
497 FILE *f
= fopen(fname
, "r");
498 size_t read
= fread(buffer
, size
, count
, f
);
500 clang_analyzer_isTainted_int(*buffer
); // expected-warning {{YES}}
501 clang_analyzer_isTainted_int(read
); // expected-warning {{YES}}
504 ssize_t
recv(int sockfd
, void *buf
, size_t len
, int flags
);
505 void testRecv(int *buf
, size_t len
, int flags
) {
507 scanf("%d", &fd
); // fake a tainted a file descriptor
509 size_t read
= recv(fd
, buf
, len
, flags
);
510 clang_analyzer_isTainted_int(*buf
); // expected-warning {{YES}}
511 clang_analyzer_isTainted_int(read
); // expected-warning {{YES}}
514 ssize_t
recvfrom(int sockfd
, void *restrict buf
, size_t len
, int flags
,
515 struct sockaddr
*restrict src_addr
,
516 socklen_t
*restrict addrlen
);
517 void testRecvfrom(int *restrict buf
, size_t len
, int flags
,
518 struct sockaddr
*restrict src_addr
,
519 socklen_t
*restrict addrlen
) {
521 scanf("%d", &fd
); // fake a tainted a file descriptor
523 size_t read
= recvfrom(fd
, buf
, len
, flags
, src_addr
, addrlen
);
524 clang_analyzer_isTainted_int(*buf
); // expected-warning {{YES}}
525 clang_analyzer_isTainted_int(read
); // expected-warning {{YES}}
528 char *ttyname(int fd
);
531 scanf("%d", &fd
); // fake a tainted a file descriptor
533 char *name
= ttyname(fd
);
534 clang_analyzer_isTainted_charp(name
); // expected-warning {{YES}}
537 int ttyname_r(int fd
, char *buf
, size_t buflen
);
538 void testTtyname_r(char *buf
, size_t buflen
) {
540 scanf("%d", &fd
); // fake a tainted a file descriptor
542 int result
= ttyname_r(fd
, buf
, buflen
);
543 clang_analyzer_isTainted_char(*buf
); // expected-warning {{YES}}
544 clang_analyzer_isTainted_int(result
); // expected-warning {{YES}}
547 char *dirname(char *path
);
552 char *name
= dirname(buf
);
553 clang_analyzer_isTainted_charp(name
); // expected-warning {{YES}}
556 char *basename(char *path
);
557 void testBasename() {
561 char *name
= basename(buf
);
562 clang_analyzer_isTainted_charp(name
); // expected-warning {{YES}}
565 int fnmatch(const char *pattern
, const char *string
, int flags
);
566 void testFnmatch(const char *pattern
, int flags
) {
568 scanf("%9s", string
);
570 int result
= fnmatch(pattern
, string
, flags
);
571 clang_analyzer_isTainted_int(result
); // expected-warning {{YES}}
574 void *memchr(const void *s
, int c
, size_t n
);
575 void testMemchr(int c
, size_t n
) {
579 char *result
= memchr(buf
, c
, n
);
580 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
583 void *memrchr(const void *s
, int c
, size_t n
);
584 void testMemrchr(int c
, size_t n
) {
588 char *result
= memrchr(buf
, c
, n
);
589 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
592 void *rawmemchr(const void *s
, int c
);
593 void testRawmemchr(int c
) {
597 char *result
= rawmemchr(buf
, c
);
598 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
601 typedef char wchar_t;
602 int mbtowc(wchar_t *pwc
, const char *s
, size_t n
);
603 void testMbtowc(wchar_t *pwc
, size_t n
) {
607 int result
= mbtowc(pwc
, buf
, n
);
608 clang_analyzer_isTainted_char(*pwc
); // expected-warning {{YES}}
609 clang_analyzer_isTainted_int(result
); // expected-warning {{YES}}
612 int wctomb(char *s
, wchar_t wc
);
613 void testWctomb(char *buf
) {
617 int result
= wctomb(buf
, wc
);
618 clang_analyzer_isTainted_char(*buf
); // expected-warning {{YES}}
619 clang_analyzer_isTainted_int(result
); // expected-warning {{YES}}
622 int wcwidth(wchar_t c
);
627 int width
= wcwidth(wc
);
628 clang_analyzer_isTainted_int(width
); // expected-warning {{YES}}
631 int memcmp(const void *s1
, const void *s2
, size_t n
);
632 void testMemcmpWithLHSTainted(size_t n
, char *rhs
) {
636 int cmp_result
= memcmp(lhs
, rhs
, n
);
637 clang_analyzer_isTainted_int(cmp_result
); // expected-warning {{YES}}
640 void testMemcmpWithRHSTainted(size_t n
, char *lhs
) {
644 int cmp_result
= memcmp(lhs
, rhs
, n
);
645 clang_analyzer_isTainted_int(cmp_result
); // expected-warning {{YES}}
648 void *memcpy(void *restrict dest
, const void *restrict src
, size_t n
);
649 void testMemcpy(char *dst
, size_t n
) {
653 char *result
= memcpy(dst
, src
, n
);
655 clang_analyzer_isTainted_char(*dst
); // expected-warning {{YES}}
656 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
659 void *memmove(void *dest
, const void *src
, size_t n
);
660 void testMemmove(char *dst
, size_t n
) {
664 char *result
= memmove(dst
, src
, n
);
666 clang_analyzer_isTainted_char(*dst
); // expected-warning {{YES}}
667 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
670 void *memmem(const void *haystack
, size_t haystacklen
, const void *needle
, size_t needlelen
);
671 void testMemmem(const void *needle
, size_t needlelen
) {
673 scanf("%9s", haystack
);
675 char *result
= memmem(haystack
, 9, needle
, needlelen
);
676 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
679 char *strstr(const char *haystack
, const char *needle
);
680 void testStrstr(const char *needle
) {
682 scanf("%9s", haystack
);
684 char *result
= strstr(haystack
, needle
);
685 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
688 char *strcasestr(const char *haystack
, const char *needle
);
689 void testStrcasestr(const char *needle
) {
691 scanf("%9s", haystack
);
693 char *result
= strcasestr(haystack
, needle
);
694 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
697 char *strchrnul(const char *s
, int c
);
698 void testStrchrnul() {
702 char *result
= strchrnul(s
, 9);
703 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
706 char *index(const char *s
, int c
);
711 char *result
= index(s
, 9);
712 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
715 char *rindex(const char *s
, int c
);
720 char *result
= rindex(s
, 9);
721 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
724 int strcmp(const char *s1
, const char *s2
);
725 void testStrcmpWithLHSTainted(char *rhs
) {
729 int cmp_result
= strcmp(lhs
, rhs
);
730 clang_analyzer_isTainted_int(cmp_result
); // expected-warning {{YES}}
733 void testStrcmpWithRHSTainted(char *lhs
) {
737 int cmp_result
= strcmp(lhs
, rhs
);
738 clang_analyzer_isTainted_int(cmp_result
); // expected-warning {{YES}}
740 int strcasecmp(const char *s1
, const char *s2
);
741 void testStrcasecmpWithLHSTainted(char *rhs
) {
745 int cmp_result
= strcasecmp(lhs
, rhs
);
746 clang_analyzer_isTainted_int(cmp_result
); // expected-warning {{YES}}
749 void testStrcasecmpWithRHSTainted(char *lhs
) {
753 int cmp_result
= strcasecmp(lhs
, rhs
);
754 clang_analyzer_isTainted_int(cmp_result
); // expected-warning {{YES}}
756 int strncmp(const char *s1
, const char *s2
, size_t n
);
757 void testStrncmpWithLHSTainted(char *rhs
, size_t n
) {
761 int cmp_result
= strncmp(lhs
, rhs
, n
);
762 clang_analyzer_isTainted_int(cmp_result
); // expected-warning {{YES}}
765 void testStrncmpWithRHSTainted(char *lhs
, size_t n
) {
769 int cmp_result
= strncmp(lhs
, rhs
, n
);
770 clang_analyzer_isTainted_int(cmp_result
); // expected-warning {{YES}}
773 void testStrncmpWithNTainted(char *lhs
, char *rhs
) {
777 int cmp_result
= strncmp(lhs
, rhs
, n
);
778 clang_analyzer_isTainted_int(cmp_result
); // expected-warning {{YES}}
781 int strncasecmp(const char *s1
, const char *s2
, size_t n
);
782 void testStrncasecmpWithLHSTainted(char *rhs
, size_t n
) {
786 int cmp_result
= strncmp(lhs
, rhs
, n
);
787 clang_analyzer_isTainted_int(cmp_result
); // expected-warning {{YES}}
790 void testStrncasecmpWithRHSTainted(char *lhs
, size_t n
) {
794 int cmp_result
= strncmp(lhs
, rhs
, n
);
795 clang_analyzer_isTainted_int(cmp_result
); // expected-warning {{YES}}
798 void testStrncasecmpWithNTainted(char *lhs
, char *rhs
) {
802 int cmp_result
= strncmp(lhs
, rhs
, n
);
803 clang_analyzer_isTainted_int(cmp_result
); // expected-warning {{YES}}
806 size_t strspn(const char *s
, const char *accept
);
807 void testStrspnFirstArgTainted(const char *accept
) {
811 size_t result
= strspn(s
, accept
);
812 clang_analyzer_isTainted_int(result
); // expected-warning {{YES}}
815 void testStrspnSecondArgTainted(const char *s
) {
817 scanf("%9s", accept
);
819 size_t result
= strspn(s
, accept
);
820 clang_analyzer_isTainted_int(result
); // expected-warning {{YES}}
823 size_t strcspn(const char *s
, const char *reject
);
824 void testStrcspnFirstArgTainted(const char *reject
) {
828 size_t result
= strcspn(s
, reject
);
829 clang_analyzer_isTainted_int(result
); // expected-warning {{YES}}
832 void testStrcspnSecondArgTainted(const char *s
) {
834 scanf("%9s", reject
);
836 size_t result
= strcspn(s
, reject
);
837 clang_analyzer_isTainted_int(result
); // expected-warning {{YES}}
840 char *strpbrk(const char *s
, const char *accept
);
841 void testStrpbrk(const char *accept
) {
845 char *result
= strpbrk(s
, accept
);
846 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
849 char *strndup(const char *s
, size_t n
);
850 void testStrndup(size_t n
) {
854 char *result
= strndup(s
, n
);
855 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
858 char *strdupa(const char *s
);
863 char *result
= strdupa(s
);
864 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
867 char *strndupa(const char *s
, size_t n
);
868 void testStrndupa(size_t n
) {
872 char *result
= strndupa(s
, n
);
873 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
876 size_t strlen(const char *s
);
881 size_t result
= strlen(s
);
882 clang_analyzer_isTainted_int(result
); // expected-warning {{YES}}
885 size_t strnlen(const char *s
, size_t maxlen
);
886 void testStrnlen(size_t maxlen
) {
890 size_t result
= strnlen(s
, maxlen
);
891 clang_analyzer_isTainted_int(result
); // expected-warning {{YES}}
894 long strtol(const char *restrict nptr
, char **restrict endptr
, int base
);
895 long long strtoll(const char *restrict nptr
, char **restrict endptr
, int base
);
896 unsigned long int strtoul(const char *nptr
, char **endptr
, int base
);
897 unsigned long long int strtoull(const char *nptr
, char **endptr
, int base
);
898 void testStrtolVariants(char **restrict endptr
, int base
) {
902 long result_l
= strtol(s
, endptr
, base
);
903 clang_analyzer_isTainted_int(result_l
); // expected-warning {{YES}}
905 long long result_ll
= strtoll(s
, endptr
, base
);
906 clang_analyzer_isTainted_int(result_ll
); // expected-warning {{YES}}
908 unsigned long result_ul
= strtoul(s
, endptr
, base
);
909 clang_analyzer_isTainted_int(result_ul
); // expected-warning {{YES}}
911 unsigned long long result_ull
= strtoull(s
, endptr
, base
);
912 clang_analyzer_isTainted_int(result_ull
); // expected-warning {{YES}}
929 void testIsFunctions() {
933 int alnum
= isalnum(c
);
934 clang_analyzer_isTainted_int(alnum
); // expected-warning {{YES}}
936 int alpha
= isalpha(c
);
937 clang_analyzer_isTainted_int(alpha
); // expected-warning {{YES}}
939 int ascii
= isascii(c
);
940 clang_analyzer_isTainted_int(ascii
); // expected-warning {{YES}}
942 int blank
= isblank(c
);
943 clang_analyzer_isTainted_int(blank
); // expected-warning {{YES}}
945 int cntrl
= iscntrl(c
);
946 clang_analyzer_isTainted_int(cntrl
); // expected-warning {{YES}}
948 int digit
= isdigit(c
);
949 clang_analyzer_isTainted_int(digit
); // expected-warning {{YES}}
951 int graph
= isgraph(c
);
952 clang_analyzer_isTainted_int(graph
); // expected-warning {{YES}}
954 int lower
= islower(c
);
955 clang_analyzer_isTainted_int(lower
); // expected-warning {{YES}}
957 int print
= isprint(c
);
958 clang_analyzer_isTainted_int(print
); // expected-warning {{YES}}
960 int punct
= ispunct(c
);
961 clang_analyzer_isTainted_int(punct
); // expected-warning {{YES}}
963 int space
= isspace(c
);
964 clang_analyzer_isTainted_int(space
); // expected-warning {{YES}}
966 int upper
= isupper(c
);
967 clang_analyzer_isTainted_int(upper
); // expected-warning {{YES}}
969 int xdigit
= isxdigit(c
);
970 clang_analyzer_isTainted_int(xdigit
); // expected-warning {{YES}}
973 void qsort(void *base
, size_t nmemb
, size_t size
, int (*compar
)(const void *, const void *));
974 void qsort_r(void *base
, size_t nmemb
, size_t size
, int (*compar
)(const void *, const void *, void *), void *arg
);
979 qsort(data
, sizeof(data
), sizeof(data
[0]), NULL
);
980 clang_analyzer_isTainted_int(data
[0]); // expected-warning {{YES}}
981 qsort_r(data
, sizeof(data
), sizeof(data
[0]), NULL
, NULL
);
982 clang_analyzer_isTainted_int(data
[0]); // expected-warning {{YES}}
985 // Test configuration
987 void mySource2(int*);
988 void myScanf(const char*, ...);
989 int myPropagator(int, int*);
990 int mySnprintf(char*, size_t, const char*, ...);
991 bool isOutOfRange(const int*);
992 void mySink(int, int, int);
994 void testConfigurationSources1(void) {
996 Buffer
[x
] = 1; // expected-warning {{Out of bound memory access }}
999 void testConfigurationSources2(void) {
1002 Buffer
[x
] = 1; // expected-warning {{Out of bound memory access }}
1005 void testConfigurationSources3(void) {
1007 myScanf("%d %d", &x
, &y
);
1008 Buffer
[y
] = 1; // expected-warning {{Out of bound memory access }}
1011 void testConfigurationPropagation(void) {
1012 int x
= mySource1();
1014 myPropagator(x
, &y
);
1015 Buffer
[y
] = 1; // expected-warning {{Out of bound memory access }}
1018 void testConfigurationFilter(void) {
1019 int x
= mySource1();
1020 if (isOutOfRange(&x
)) // the filter function
1022 Buffer
[x
] = 1; // no-warning
1025 void testConfigurationSinks(void) {
1026 int x
= mySource1();
1028 // expected-warning@-1 {{Untrusted data is passed to a user-defined sink}}
1029 mySink(1, x
, 2); // no-warning
1031 // expected-warning@-1 {{Untrusted data is passed to a user-defined sink}}
1034 void testUnknownFunction(void (*foo
)(void)) {
1038 void testProctitleFalseNegative(void) {
1040 fscanf(stdin
, "%79s", flag
);
1041 char *argv
[] = {"myapp", flag
};
1042 // FIXME: We should have a warning below: Untrusted data passed to sink.
1043 setproctitle_init(1, argv
, 0);
1046 void testProctitle2(char *real_argv
[]) {
1047 char *app
= getenv("APP_NAME");
1050 char *argv
[] = {app
, "--foobar"};
1051 setproctitle_init(1, argv
, 0); // expected-warning {{Untrusted data is passed to a user-defined sink}}
1052 setproctitle_init(1, real_argv
, argv
); // expected-warning {{Untrusted data is passed to a user-defined sink}}