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 typedef __typeof(sizeof(int)) size_t;
60 typedef signed long long ssize_t
;
61 typedef __WCHAR_TYPE__
wchar_t;
62 void clang_analyzer_isTainted_char(char);
63 void clang_analyzer_isTainted_wchar(wchar_t);
64 void clang_analyzer_isTainted_charp(char*);
65 void clang_analyzer_isTainted_int(int);
69 int scanf(const char *restrict format
, ...);
70 char *gets(char *str
);
71 char *gets_s(char *str
, rsize_t n
);
74 typedef struct _FILE
FILE;
76 extern struct _FILE
*stdin
;
84 wchar_t *fgetws(wchar_t *ws
, int n
, FILE *stream
);
85 wchar_t *wmemset(wchar_t *wcs
, wchar_t wc
, unsigned long n
);
86 wchar_t *wmemcpy(wchar_t *dest
, const wchar_t *src
, size_t n
);
87 wchar_t *wmemmove(wchar_t *dest
, const wchar_t *src
, size_t n
);
88 size_t wcslen(const wchar_t *s
);
89 wchar_t *wcscpy(wchar_t * dest
, const wchar_t * src
);
90 wchar_t *wcsncpy(wchar_t *dest
, const wchar_t *src
, size_t n
);
91 wchar_t *wcscat(wchar_t *dest
, const wchar_t *src
);
92 wchar_t *wcsncat(wchar_t *dest
,const wchar_t *src
, size_t n
);
93 int swprintf(wchar_t *wcs
, size_t maxlen
, const wchar_t *format
, ...);
95 char *getenv(const char *name
);
97 FILE *fopen(const char *name
, const char *mode
);
99 int fscanf(FILE *restrict stream
, const char *restrict format
, ...);
100 int sprintf(char *str
, const char *format
, ...);
101 void setproctitle(const char *fmt
, ...);
102 void setproctitle_init(int argc
, char *argv
[], char *envp
[]);
104 // Define string functions. Use builtin for some of them. They all default to
105 // the processing in the taint checker.
106 #define strcpy(dest, src) \
107 ((__builtin_object_size(dest, 0) != -1ULL) \
108 ? __builtin___strcpy_chk (dest, src, __builtin_object_size(dest, 1)) \
109 : __inline_strcpy_chk(dest, src))
111 static char *__inline_strcpy_chk (char *dest
, const char *src
) {
112 return __builtin___strcpy_chk(dest
, src
, __builtin_object_size(dest
, 1));
114 char *stpcpy(char *restrict s1
, const char *restrict s2
);
115 char *strncpy( char * destination
, const char * source
, size_t num
);
116 char *strndup(const char *s
, size_t n
);
117 char *strncat(char *restrict s1
, const char *restrict s2
, size_t n
);
119 void *malloc(size_t);
120 void *calloc(size_t nmemb
, size_t size
);
121 void bcopy(void *s1
, void *s2
, size_t n
);
124 // function | pathname | filename | fd | arglist | argv[] | envp[]
125 // ===============================================================
126 // 1 execl | X | | | X | |
127 // 2 execle | X | | | X | | X
128 // 3 execlp | | X | | X | |
129 // 4 execv | X | | | | X |
130 // 5 execve | X | | | | X | X
131 // 6 execvp | | X | | | X |
132 // 7 execvpe | | X | | | X | X
133 // 8 fexecve | | | X | | X | X
134 // ===============================================================
135 // letter | | p | f | l | v | e
138 // - pathname: rel/abs path to the binary
139 // - filename: file name searched in PATH to execute the binary
140 // - fd: accepts a file descriptor
141 // - arglist: accepts variadic arguments
142 // - argv: accepts a pointer to array, denoting the new argv
143 // - envp: accepts a pointer to array, denoting the new envp
145 int execl(const char *path
, const char *arg
, ...);
146 int execle(const char *path
, const char *arg
, ...);
147 int execlp(const char *file
, const char *arg
, ...);
148 int execv(const char *path
, char *const argv
[]);
149 int execve(const char *path
, char *const argv
[], char *const envp
[]);
150 int execvp(const char *file
, char *const argv
[]);
151 int execvpe(const char *file
, char *const argv
[], char *const envp
[]);
152 int fexecve(int fd
, char *const argv
[], char *const envp
[]);
153 FILE *popen(const char *command
, const char *type
);
154 int pclose(FILE *stream
);
155 int system(const char *command
);
158 typedef size_t socklen_t
;
161 unsigned short sa_family
;
168 void bufferScanfDirect(void)
172 Buffer
[n
] = 1; // expected-warning {{Out of bound memory access }}
175 void bufferScanfArithmetic1(int x
) {
179 Buffer
[m
] = 1; // expected-warning {{Out of bound memory access }}
182 void bufferScanfArithmetic2(int x
) {
185 int m
= 100 - (n
+ 3) * x
;
186 Buffer
[m
] = 1; // expected-warning {{Out of bound memory access }}
189 void bufferScanfAssignment(int x
) {
195 Buffer
[m
] = 1; // expected-warning {{Out of bound memory access }}
199 void scanfArg(void) {
201 scanf("%d", t
); // expected-warning {{format specifies type 'int *' but the argument has type 'int'}}
204 void bufferGetchar(int x
) {
206 Buffer
[m
] = 1; //expected-warning {{Out of bound memory access (index is tainted)}}
209 extern const unsigned short int **__ctype_b_loc (void);
210 enum { _ISdigit
= 2048 };
211 # define isdigit(c) ((*__ctype_b_loc ())[(int) (c)] & (unsigned short int) _ISdigit)
213 int isdigitImplFalsePositive(void) {
214 // If this code no longer produces a bug report, then consider removing the
215 // special case that disables buffer overflow reports coming from the isXXXXX
216 // macros in ctypes.h.
218 return ((*__ctype_b_loc ())[(int) (c
)] & (unsigned short int) _ISdigit
);
219 //expected-warning@-1 {{Out of bound memory access (index is tainted)}}
222 int isdigitSuppressed(void) {
223 // Same code as above, but reports are suppressed based on macro name:
225 return isdigit(c
); //no-warning
228 // Some later tests use isdigit as a function, so we need to undef it:
231 void testUncontrolledFormatString(char **p
) {
233 fscanf(stdin
, "%s", s
);
235 sprintf(buf
,s
); // expected-warning {{Uncontrolled Format String}}
236 setproctitle(s
, 3); // expected-warning {{Uncontrolled Format String}}
238 // Test taint propagation through strcpy and family.
241 sprintf(buf
,scpy
); // expected-warning {{Uncontrolled Format String}}
243 stpcpy(*(++p
), s
); // this generates __inline.
244 setproctitle(*(p
), 3); // expected-warning {{Uncontrolled Format String}}
248 setproctitle(spcpy
, 3); // expected-warning {{Uncontrolled Format String}}
251 spcpyret
= stpcpy(spcpy
, s
);
252 setproctitle(spcpyret
, 3); // expected-warning {{Uncontrolled Format String}}
255 strncpy(sncpy
, s
, 20);
256 setproctitle(sncpy
, 3); // expected-warning {{Uncontrolled Format String}}
259 dup
= strndup(s
, 20);
260 setproctitle(dup
, 3); // expected-warning {{Uncontrolled Format String}}
264 void testTaintSystemCall(void) {
268 system(addr
); // expected-warning {{Untrusted data is passed to a system call}}
270 // Test that spintf transfers taint.
271 sprintf(buffer
, "/bin/mail %s < /tmp/email", addr
);
272 system(buffer
); // expected-warning {{Untrusted data is passed to a system call}}
275 void testTaintSystemCall2(void) {
276 // Test that snpintf transfers taint.
280 __builtin_snprintf(buffern
, 10, "/bin/mail %s < /tmp/email", addr
);
281 // expected-warning@-1 {{'snprintf' will always be truncated; specified size is 10, but format string expands to at least 24}}
282 system(buffern
); // expected-warning {{Untrusted data is passed to a system call}}
285 void testTaintSystemCall3(void) {
289 scanf("%s %d", addr
, &numt
);
290 __builtin_snprintf(buffern2
, numt
, "/bin/mail %s < /tmp/email", "abcd");
291 system(buffern2
); // expected-warning {{Untrusted data is passed to a system call}}
294 void testGets(void) {
297 system(str
); // expected-warning {{Untrusted data is passed to a system call}}
300 void testGets_s(void) {
303 system(str
); // expected-warning {{Untrusted data is passed to a system call}}
306 void testTaintedBufferSize(void) {
310 int *buf1
= (int*)malloc(ts
*sizeof(int)); // expected-warning {{Untrusted data is used to specify the buffer size}}
311 char *dst
= (char*)calloc(ts
, sizeof(char)); //expected-warning {{Untrusted data is used to specify the buffer size}}
312 bcopy(buf1
, dst
, ts
); // expected-warning {{Untrusted data is used to specify the buffer size}}
313 __builtin_memcpy(dst
, buf1
, (ts
+ 4)*sizeof(char)); // expected-warning {{Untrusted data is used to specify the buffer size}}
315 // If both buffers are trusted, do not issue a warning.
316 char *dst2
= (char*)malloc(ts
*sizeof(char)); // expected-warning {{Untrusted data is used to specify the buffer size}}
317 strncat(dst2
, dst
, ts
); // no-warning
320 #define AF_UNIX 1 /* local to host (pipes) */
321 #define AF_INET 2 /* internetwork: UDP, TCP, etc. */
322 #define AF_LOCAL AF_UNIX /* backward compatibility */
323 #define SOCK_STREAM 1
324 int socket(int, int, int);
325 size_t read(int, void *, size_t);
327 void testSocket(void) {
331 sock
= socket(AF_INET
, SOCK_STREAM
, 0);
332 read(sock
, buffer
, 100);
333 execl(buffer
, "filename", 0); // expected-warning {{Untrusted data is passed to a system call}}
335 sock
= socket(AF_LOCAL
, SOCK_STREAM
, 0);
336 read(sock
, buffer
, 100);
337 execl(buffer
, "filename", 0); // no-warning
339 sock
= socket(AF_INET
, SOCK_STREAM
, 0);
340 // References to both buffer and &buffer as an argument should taint the argument
341 read(sock
, &buffer
, 100);
342 execl(buffer
, "filename", 0); // expected-warning {{Untrusted data is passed to a system call}}
345 void testStruct(void) {
354 sock
= socket(AF_INET
, SOCK_STREAM
, 0);
355 read(sock
, &tainted
, sizeof(tainted
));
356 __builtin_memcpy(buffer
, tainted
.buf
, tainted
.length
); // expected-warning {{Untrusted data is used to specify the buffer size}}
359 void testStructArray(void) {
364 char dstbuf
[16], srcbuf
[16];
367 sock
= socket(AF_INET
, SOCK_STREAM
, 0);
368 __builtin_memset(srcbuf
, 0, sizeof(srcbuf
));
370 read(sock
, &tainted
[0], sizeof(tainted
));
371 __builtin_memcpy(dstbuf
, srcbuf
, tainted
[0].length
); // expected-warning {{Untrusted data is used to specify the buffer size}}
373 __builtin_memset(&tainted
, 0, sizeof(tainted
));
374 read(sock
, &tainted
, sizeof(tainted
));
375 __builtin_memcpy(dstbuf
, srcbuf
, tainted
[0].length
); // expected-warning {{Untrusted data is used to specify the buffer size}}
377 __builtin_memset(&tainted
, 0, sizeof(tainted
));
378 // If we taint element 1, we should not raise an alert on taint for element 0 or element 2
379 read(sock
, &tainted
[1], sizeof(tainted
));
380 __builtin_memcpy(dstbuf
, srcbuf
, tainted
[0].length
); // no-warning
381 __builtin_memcpy(dstbuf
, srcbuf
, tainted
[2].length
); // no-warning
384 void testUnion(void) {
392 int sock
= socket(AF_INET
, SOCK_STREAM
, 0);
393 read(sock
, &tainted
.y
, sizeof(tainted
.y
));
394 // FIXME: overlapping regions aren't detected by isTainted yet
395 __builtin_memcpy(buffer
, tainted
.y
, tainted
.x
);
398 int testDivByZero(void) {
401 return 5/x
; // expected-warning {{Division by a tainted value, possibly zero}}
405 void testTaintedVLASize(void) {
408 int vla
[x
]; // expected-warning{{Declared variable-length array (VLA) has tainted size}}
411 int testTaintedAllocaMem() {
415 p
= __builtin_alloca(1);
416 __builtin_memcpy(p
, &x
, 1);
417 return 5 / *(char*)p
; // expected-warning {{Division by a tainted value, possibly zero}}
420 int testTaintedMallocMem() {
425 __builtin_memcpy(p
, &x
, 1);
426 return 5 / *(char*)p
; // expected-warning {{Division by a tainted value, possibly zero}}
430 // This computation used to take a very long time.
431 #define longcmp(a,b,c) { \
432 a -= c; a ^= c; c += b; b -= a; b ^= (a<<6) | (a >> (32-b)); a += c; c -= b; c ^= b; b += a; \
433 a -= c; a ^= c; c += b; b -= a; b ^= a; a += c; c -= b; c ^= b; b += a; }
435 unsigned radar11369570_hanging(const unsigned char *arr
, int l
) {
437 a
= b
= c
= 0x9899e3 + l
;
443 a
+= (arr
[3] + ((unsigned) arr
[2] << 8) + ((unsigned) arr
[1] << 16) + ((unsigned) arr
[0] << 24));
447 return 5/a
; // expected-warning {{Division by a tainted value, possibly zero}}
450 // Check that we do not assert of the following code.
451 int SymSymExprWithDiffTypes(void* p
) {
454 int j
= (i
% (int)(long)p
);
455 return 5/j
; // expected-warning {{Division by a tainted value, possibly zero}}
459 void constraintManagerShouldTreatAsOpaque(int rhs
) {
462 // This comparison used to hit an assertion in the constraint manager,
463 // which didn't handle NonLoc sym-sym comparisons.
467 *(volatile int *) 0; // no-warning
470 int testSprintf_is_not_a_source(char *buf
, char *msg
) {
471 int x
= sprintf(buf
, "%s", msg
); // no-warning
472 return 1 / x
; // no-warning: 'sprintf' is not a taint source
475 int testSprintf_propagates_taint(char *buf
, char *msg
) {
477 int x
= sprintf(buf
, "%s", msg
); // propagate taint!
478 return 1 / x
; // expected-warning {{Division by a tainted value, possibly zero}}
481 void test_wchar_apis_dont_propagate(const char *path
) {
482 // strlen, wcslen, strnlen and alike intentionally don't propagate taint.
483 // See the details here: https://github.com/llvm/llvm-project/pull/66086
484 // This isn't ideal, but this is only what we have now.
486 FILE *f
= fopen(path
, "r");
487 clang_analyzer_isTainted_charp((char*)f
); // expected-warning {{YES}}
489 fgetws(wbuf
, sizeof(wbuf
)/sizeof(*wbuf
), f
);
490 clang_analyzer_isTainted_wchar(*wbuf
); // expected-warning {{YES}}
491 int n
= wcslen(wbuf
);
492 clang_analyzer_isTainted_int(n
); // expected-warning {{NO}}
494 wchar_t dst
[100] = L
"ABC";
495 clang_analyzer_isTainted_wchar(*dst
); // expected-warning {{NO}}
496 wcsncat(dst
, wbuf
, sizeof(wbuf
)/sizeof(*wbuf
));
497 clang_analyzer_isTainted_wchar(*dst
); // expected-warning {{YES}}
500 clang_analyzer_isTainted_int(m
); // expected-warning {{NO}}
503 int scanf_s(const char *format
, ...);
504 int testScanf_s_(int *out
) {
506 return 1 / *out
; // expected-warning {{Division by a tainted value, possibly zero}}
509 #define _IO_FILE FILE
510 int _IO_getc(_IO_FILE
*__fp
);
511 int testUnderscoreIO_getc(_IO_FILE
*fp
) {
512 char c
= _IO_getc(fp
);
513 return 1 / c
; // expected-warning {{Division by a tainted value, possibly zero}}
516 char *getcwd(char *buf
, size_t size
);
517 int testGetcwd(char *buf
, size_t size
) {
518 char *c
= getcwd(buf
, size
);
519 return system(c
); // expected-warning {{Untrusted data is passed to a system call}}
522 char *getwd(char *buf
);
523 int testGetwd(char *buf
) {
524 char *c
= getwd(buf
);
525 return system(c
); // expected-warning {{Untrusted data is passed to a system call}}
528 ssize_t
readlink(const char *path
, char *buf
, size_t bufsiz
);
529 int testReadlink(char *path
, char *buf
, size_t bufsiz
) {
530 ssize_t s
= readlink(path
, buf
, bufsiz
);
531 system(buf
); // expected-warning {{Untrusted data is passed to a system call}}
532 // readlink never returns 0
533 return 1 / (s
+ 1); // expected-warning {{Division by a tainted value, possibly zero}}
536 ssize_t
readlinkat(int dirfd
, const char *pathname
, char *buf
, size_t bufsiz
);
537 int testReadlinkat(int dirfd
, char *path
, char *buf
, size_t bufsiz
) {
538 ssize_t s
= readlinkat(dirfd
, path
, buf
, bufsiz
);
539 system(buf
); // expected-warning {{Untrusted data is passed to a system call}}
540 (void)(1 / dirfd
); // arg 0 is not tainted
541 system(path
); // arg 1 is not tainted
542 (void)(1 / bufsiz
); // arg 3 is not tainted
543 // readlinkat never returns 0
544 return 1 / (s
+ 1); // expected-warning {{Division by a tainted value, possibly zero}}
547 char *get_current_dir_name(void);
548 int testGet_current_dir_name() {
549 char *d
= get_current_dir_name();
550 return system(d
); // expected-warning {{Untrusted data is passed to a system call}}
553 int gethostname(char *name
, size_t len
);
554 int testGethostname(char *name
, size_t len
) {
555 gethostname(name
, len
);
556 return system(name
); // expected-warning {{Untrusted data is passed to a system call}}
559 int getnameinfo(const struct sockaddr
*restrict addr
, socklen_t addrlen
,
560 char *restrict host
, socklen_t hostlen
,
561 char *restrict serv
, socklen_t servlen
, int flags
);
562 int testGetnameinfo(const struct sockaddr
*restrict addr
, socklen_t addrlen
,
563 char *restrict host
, socklen_t hostlen
,
564 char *restrict serv
, socklen_t servlen
, int flags
) {
565 getnameinfo(addr
, addrlen
, host
, hostlen
, serv
, servlen
, flags
);
567 system(host
); // expected-warning {{Untrusted data is passed to a system call}}
568 return system(serv
); // expected-warning {{Untrusted data is passed to a system call}}
571 int getseuserbyname(const char *linuxuser
, char **selinuxuser
, char **level
);
572 int testGetseuserbyname(const char *linuxuser
, char **selinuxuser
, char **level
) {
573 getseuserbyname(linuxuser
, selinuxuser
, level
);
574 system(selinuxuser
[0]); // expected-warning {{Untrusted data is passed to a system call}}
575 return system(level
[0]); // expected-warning {{Untrusted data is passed to a system call}}
579 int getgroups(int size
, gid_t list
[]);
580 int testGetgroups(int size
, gid_t list
[], bool flag
) {
581 int result
= getgroups(size
, list
);
583 return 1 / list
[0]; // expected-warning {{Division by a tainted value, possibly zero}}
585 return 1 / (result
+ 1); // expected-warning {{Division by a tainted value, possibly zero}}
588 char *getlogin(void);
590 char *n
= getlogin();
591 return system(n
); // expected-warning {{Untrusted data is passed to a system call}}
594 int getlogin_r(char *buf
, size_t bufsize
);
595 int testGetlogin_r(char *buf
, size_t bufsize
) {
596 getlogin_r(buf
, bufsize
);
597 return system(buf
); // expected-warning {{Untrusted data is passed to a system call}}
600 int fscanf_s(FILE *stream
, const char *format
, ...);
601 void testFscanf_s(const char *fname
, int *d
) {
602 FILE *f
= fopen(fname
, "r");
603 fscanf_s(f
, "%d", d
);
604 clang_analyzer_isTainted_int(*d
); // expected-warning {{YES}}
607 int fread(void *buffer
, size_t size
, size_t count
, FILE *stream
);
608 void testFread(const char *fname
, int *buffer
, size_t size
, size_t count
) {
609 FILE *f
= fopen(fname
, "r");
610 size_t read
= fread(buffer
, size
, count
, f
);
612 clang_analyzer_isTainted_int(*buffer
); // expected-warning {{YES}}
613 clang_analyzer_isTainted_int(read
); // expected-warning {{YES}}
616 ssize_t
recv(int sockfd
, void *buf
, size_t len
, int flags
);
617 int accept(int fd
, struct sockaddr
*addr
, socklen_t
*addrlen
);
618 int bind(int fd
, const struct sockaddr
*addr
, socklen_t addrlen
);
619 int listen(int fd
, int backlog
);
621 void testRecv(int *buf
, size_t len
, int flags
) {
623 scanf("%d", &fd
); // fake a tainted a file descriptor
625 size_t read
= recv(fd
, buf
, len
, flags
);
626 clang_analyzer_isTainted_int(*buf
); // expected-warning {{YES}}
627 clang_analyzer_isTainted_int(read
); // expected-warning {{YES}}
630 ssize_t
recvfrom(int sockfd
, void *restrict buf
, size_t len
, int flags
,
631 struct sockaddr
*restrict src_addr
,
632 socklen_t
*restrict addrlen
);
633 void testRecvfrom(int *restrict buf
, size_t len
, int flags
,
634 struct sockaddr
*restrict src_addr
,
635 socklen_t
*restrict addrlen
) {
637 scanf("%d", &fd
); // fake a tainted a file descriptor
639 size_t read
= recvfrom(fd
, buf
, len
, flags
, src_addr
, addrlen
);
640 clang_analyzer_isTainted_int(*buf
); // expected-warning {{YES}}
641 clang_analyzer_isTainted_int(read
); // expected-warning {{YES}}
644 char *ttyname(int fd
);
647 scanf("%d", &fd
); // fake a tainted a file descriptor
649 char *name
= ttyname(fd
);
650 clang_analyzer_isTainted_charp(name
); // expected-warning {{YES}}
653 int ttyname_r(int fd
, char *buf
, size_t buflen
);
654 void testTtyname_r(char *buf
, size_t buflen
) {
656 scanf("%d", &fd
); // fake a tainted a file descriptor
658 int result
= ttyname_r(fd
, buf
, buflen
);
659 clang_analyzer_isTainted_char(*buf
); // expected-warning {{YES}}
660 clang_analyzer_isTainted_int(result
); // expected-warning {{YES}}
663 char *dirname(char *path
);
668 char *name
= dirname(buf
);
669 clang_analyzer_isTainted_charp(name
); // expected-warning {{YES}}
672 char *basename(char *path
);
673 void testBasename() {
677 char *name
= basename(buf
);
678 clang_analyzer_isTainted_charp(name
); // expected-warning {{YES}}
681 int fnmatch(const char *pattern
, const char *string
, int flags
);
682 void testFnmatch(const char *pattern
, int flags
) {
684 scanf("%9s", string
);
686 int result
= fnmatch(pattern
, string
, flags
);
687 clang_analyzer_isTainted_int(result
); // expected-warning {{YES}}
690 void *memchr(const void *s
, int c
, size_t n
);
691 void testMemchr(int c
, size_t n
) {
695 char *result
= memchr(buf
, c
, n
);
696 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
699 void *memrchr(const void *s
, int c
, size_t n
);
700 void testMemrchr(int c
, size_t n
) {
704 char *result
= memrchr(buf
, c
, n
);
705 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
708 void *rawmemchr(const void *s
, int c
);
709 void testRawmemchr(int c
) {
713 char *result
= rawmemchr(buf
, c
);
714 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
717 int mbtowc(wchar_t *pwc
, const char *s
, size_t n
);
718 void testMbtowc(wchar_t *pwc
, size_t n
) {
722 int result
= mbtowc(pwc
, buf
, n
);
723 clang_analyzer_isTainted_char(*pwc
); // expected-warning {{YES}}
724 clang_analyzer_isTainted_int(result
); // expected-warning {{YES}}
727 int wctomb(char *s
, wchar_t wc
);
728 void testWctomb(char *buf
) {
729 wchar_t wc
= getchar();
731 int result
= wctomb(buf
, wc
);
732 clang_analyzer_isTainted_char(*buf
); // expected-warning {{YES}}
733 clang_analyzer_isTainted_int(result
); // expected-warning {{YES}}
736 int wcwidth(wchar_t c
);
738 wchar_t wc
= getchar();
740 int width
= wcwidth(wc
);
741 clang_analyzer_isTainted_int(width
); // expected-warning {{YES}}
744 int memcmp(const void *s1
, const void *s2
, size_t n
);
745 void testMemcmpWithLHSTainted(size_t n
, char *rhs
) {
749 int cmp_result
= memcmp(lhs
, rhs
, n
);
750 clang_analyzer_isTainted_int(cmp_result
); // expected-warning {{YES}}
753 void testMemcmpWithRHSTainted(size_t n
, char *lhs
) {
757 int cmp_result
= memcmp(lhs
, rhs
, n
);
758 clang_analyzer_isTainted_int(cmp_result
); // expected-warning {{YES}}
761 void *memcpy(void *restrict dest
, const void *restrict src
, size_t n
);
762 void testMemcpy(char *dst
, size_t n
) {
766 char *result
= memcpy(dst
, src
, n
);
768 clang_analyzer_isTainted_char(*dst
); // expected-warning {{YES}}
769 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
772 void *memmove(void *dest
, const void *src
, size_t n
);
773 void testMemmove(char *dst
, size_t n
) {
777 char *result
= memmove(dst
, src
, n
);
779 clang_analyzer_isTainted_char(*dst
); // expected-warning {{YES}}
780 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
783 void *memmem(const void *haystack
, size_t haystacklen
, const void *needle
, size_t needlelen
);
784 void testMemmem(const void *needle
, size_t needlelen
) {
786 scanf("%9s", haystack
);
788 char *result
= memmem(haystack
, 9, needle
, needlelen
);
789 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
792 char *strstr(const char *haystack
, const char *needle
);
793 void testStrstr(const char *needle
) {
795 scanf("%9s", haystack
);
797 char *result
= strstr(haystack
, needle
);
798 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
801 char *strcasestr(const char *haystack
, const char *needle
);
802 void testStrcasestr(const char *needle
) {
804 scanf("%9s", haystack
);
806 char *result
= strcasestr(haystack
, needle
);
807 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
810 char *strchrnul(const char *s
, int c
);
811 void testStrchrnul() {
815 char *result
= strchrnul(s
, 9);
816 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
819 char *index(const char *s
, int c
);
824 char *result
= index(s
, 9);
825 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
828 char *rindex(const char *s
, int c
);
833 char *result
= rindex(s
, 9);
834 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
837 int strcmp(const char *s1
, const char *s2
);
838 void testStrcmpWithLHSTainted(char *rhs
) {
842 int cmp_result
= strcmp(lhs
, rhs
);
843 clang_analyzer_isTainted_int(cmp_result
); // expected-warning {{YES}}
846 void testStrcmpWithRHSTainted(char *lhs
) {
850 int cmp_result
= strcmp(lhs
, rhs
);
851 clang_analyzer_isTainted_int(cmp_result
); // expected-warning {{YES}}
853 int strcasecmp(const char *s1
, const char *s2
);
854 void testStrcasecmpWithLHSTainted(char *rhs
) {
858 int cmp_result
= strcasecmp(lhs
, rhs
);
859 clang_analyzer_isTainted_int(cmp_result
); // expected-warning {{YES}}
862 void testStrcasecmpWithRHSTainted(char *lhs
) {
866 int cmp_result
= strcasecmp(lhs
, rhs
);
867 clang_analyzer_isTainted_int(cmp_result
); // expected-warning {{YES}}
869 int strncmp(const char *s1
, const char *s2
, size_t n
);
870 void testStrncmpWithLHSTainted(char *rhs
, size_t n
) {
874 int cmp_result
= strncmp(lhs
, rhs
, n
);
875 clang_analyzer_isTainted_int(cmp_result
); // expected-warning {{YES}}
878 void testStrncmpWithRHSTainted(char *lhs
, size_t n
) {
882 int cmp_result
= strncmp(lhs
, rhs
, n
);
883 clang_analyzer_isTainted_int(cmp_result
); // expected-warning {{YES}}
886 void testStrncmpWithNTainted(char *lhs
, char *rhs
) {
890 int cmp_result
= strncmp(lhs
, rhs
, n
);
891 clang_analyzer_isTainted_int(cmp_result
); // expected-warning {{YES}}
894 int strncasecmp(const char *s1
, const char *s2
, size_t n
);
895 void testStrncasecmpWithLHSTainted(char *rhs
, size_t n
) {
899 int cmp_result
= strncmp(lhs
, rhs
, n
);
900 clang_analyzer_isTainted_int(cmp_result
); // expected-warning {{YES}}
903 void testStrncasecmpWithRHSTainted(char *lhs
, size_t n
) {
907 int cmp_result
= strncmp(lhs
, rhs
, n
);
908 clang_analyzer_isTainted_int(cmp_result
); // expected-warning {{YES}}
911 void testStrncasecmpWithNTainted(char *lhs
, char *rhs
) {
915 int cmp_result
= strncmp(lhs
, rhs
, n
);
916 clang_analyzer_isTainted_int(cmp_result
); // expected-warning {{YES}}
919 size_t strspn(const char *s
, const char *accept
);
920 void testStrspnFirstArgTainted(const char *accept
) {
924 size_t result
= strspn(s
, accept
);
925 clang_analyzer_isTainted_int(result
); // expected-warning {{YES}}
928 void testStrspnSecondArgTainted(const char *s
) {
930 scanf("%9s", accept
);
932 size_t result
= strspn(s
, accept
);
933 clang_analyzer_isTainted_int(result
); // expected-warning {{YES}}
936 size_t strcspn(const char *s
, const char *reject
);
937 void testStrcspnFirstArgTainted(const char *reject
) {
941 size_t result
= strcspn(s
, reject
);
942 clang_analyzer_isTainted_int(result
); // expected-warning {{YES}}
945 void testStrcspnSecondArgTainted(const char *s
) {
947 scanf("%9s", reject
);
949 size_t result
= strcspn(s
, reject
);
950 clang_analyzer_isTainted_int(result
); // expected-warning {{YES}}
953 char *strpbrk(const char *s
, const char *accept
);
954 void testStrpbrk(const char *accept
) {
958 char *result
= strpbrk(s
, accept
);
959 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
962 char *strndup(const char *s
, size_t n
);
963 void testStrndup(size_t n
) {
967 char *result
= strndup(s
, n
);
968 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
971 char *strdupa(const char *s
);
976 char *result
= strdupa(s
);
977 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
980 char *strndupa(const char *s
, size_t n
);
981 void testStrndupa(size_t n
) {
985 char *result
= strndupa(s
, n
);
986 clang_analyzer_isTainted_charp(result
); // expected-warning {{YES}}
989 size_t strlen(const char *s
);
990 void testStrlen_dont_propagate() {
991 // strlen, wcslen, strnlen and alike intentionally don't propagate taint.
992 // See the details here: https://github.com/llvm/llvm-project/pull/66086
993 // This isn't ideal, but this is only what we have now.
997 size_t result
= strlen(s
);
998 // strlen propagating taint would bring in many false positives
999 clang_analyzer_isTainted_int(result
); // expected-warning {{NO}}
1002 size_t strnlen(const char *s
, size_t maxlen
);
1003 void testStrnlen_dont_propagate(size_t maxlen
) {
1004 // strlen, wcslen, strnlen and alike intentionally don't propagate taint.
1005 // See the details here: https://github.com/llvm/llvm-project/pull/66086
1006 // This isn't ideal, but this is only what we have now.
1009 size_t result
= strnlen(s
, maxlen
);
1010 clang_analyzer_isTainted_int(result
); // expected-warning {{NO}}
1013 long strtol(const char *restrict nptr
, char **restrict endptr
, int base
);
1014 long long strtoll(const char *restrict nptr
, char **restrict endptr
, int base
);
1015 unsigned long int strtoul(const char *nptr
, char **endptr
, int base
);
1016 unsigned long long int strtoull(const char *nptr
, char **endptr
, int base
);
1017 void testStrtolVariants(char **restrict endptr
, int base
) {
1021 long result_l
= strtol(s
, endptr
, base
);
1022 clang_analyzer_isTainted_int(result_l
); // expected-warning {{YES}}
1024 long long result_ll
= strtoll(s
, endptr
, base
);
1025 clang_analyzer_isTainted_int(result_ll
); // expected-warning {{YES}}
1027 unsigned long result_ul
= strtoul(s
, endptr
, base
);
1028 clang_analyzer_isTainted_int(result_ul
); // expected-warning {{YES}}
1030 unsigned long long result_ull
= strtoull(s
, endptr
, base
);
1031 clang_analyzer_isTainted_int(result_ull
); // expected-warning {{YES}}
1046 int isxdigit(int c
);
1048 void testIsFunctions() {
1052 int alnum
= isalnum(c
);
1053 clang_analyzer_isTainted_int(alnum
); // expected-warning {{YES}}
1055 int alpha
= isalpha(c
);
1056 clang_analyzer_isTainted_int(alpha
); // expected-warning {{YES}}
1058 int ascii
= isascii(c
);
1059 clang_analyzer_isTainted_int(ascii
); // expected-warning {{YES}}
1061 int blank
= isblank(c
);
1062 clang_analyzer_isTainted_int(blank
); // expected-warning {{YES}}
1064 int cntrl
= iscntrl(c
);
1065 clang_analyzer_isTainted_int(cntrl
); // expected-warning {{YES}}
1067 int digit
= isdigit(c
);
1068 clang_analyzer_isTainted_int(digit
); // expected-warning {{YES}}
1070 int graph
= isgraph(c
);
1071 clang_analyzer_isTainted_int(graph
); // expected-warning {{YES}}
1073 int lower
= islower(c
);
1074 clang_analyzer_isTainted_int(lower
); // expected-warning {{YES}}
1076 int print
= isprint(c
);
1077 clang_analyzer_isTainted_int(print
); // expected-warning {{YES}}
1079 int punct
= ispunct(c
);
1080 clang_analyzer_isTainted_int(punct
); // expected-warning {{YES}}
1082 int space
= isspace(c
);
1083 clang_analyzer_isTainted_int(space
); // expected-warning {{YES}}
1085 int upper
= isupper(c
);
1086 clang_analyzer_isTainted_int(upper
); // expected-warning {{YES}}
1088 int xdigit
= isxdigit(c
);
1089 clang_analyzer_isTainted_int(xdigit
); // expected-warning {{YES}}
1092 void qsort(void *base
, size_t nmemb
, size_t size
, int (*compar
)(const void *, const void *));
1093 void qsort_r(void *base
, size_t nmemb
, size_t size
, int (*compar
)(const void *, const void *, void *), void *arg
);
1098 qsort(data
, sizeof(data
), sizeof(data
[0]), NULL
);
1099 clang_analyzer_isTainted_int(data
[0]); // expected-warning {{YES}}
1100 qsort_r(data
, sizeof(data
), sizeof(data
[0]), NULL
, NULL
);
1101 clang_analyzer_isTainted_int(data
[0]); // expected-warning {{YES}}
1104 // Test configuration
1105 int mySource1(void);
1106 void mySource2(int*);
1107 void myScanf(const char*, ...);
1108 int myPropagator(int, int*);
1109 int mySnprintf(char*, size_t, const char*, ...);
1110 bool isOutOfRange(const int*); // const filter function
1111 void sanitizeCmd(char*); // non-const filter function
1112 void mySink(int, int, int);
1114 void testConfigurationSources1(void) {
1115 int x
= mySource1();
1116 Buffer
[x
] = 1; // expected-warning {{Out of bound memory access }}
1119 void testConfigurationSources2(void) {
1122 Buffer
[x
] = 1; // expected-warning {{Out of bound memory access }}
1125 void testConfigurationSources3(void) {
1127 myScanf("%d %d", &x
, &y
);
1128 Buffer
[y
] = 1; // expected-warning {{Out of bound memory access }}
1131 void testConfigurationPropagation(void) {
1132 int x
= mySource1();
1134 myPropagator(x
, &y
);
1135 Buffer
[y
] = 1; // expected-warning {{Out of bound memory access }}
1138 void testConfigurationFilter(void) {
1139 int x
= mySource1();
1140 if (isOutOfRange(&x
)) // the filter function
1142 Buffer
[x
] = 1; // no-warning
1145 void testConfigurationFilterNonConst(void) {
1147 myScanf("%s", buffer
); // makes buffer tainted
1148 system(buffer
); // expected-warning {{Untrusted data is passed to a system call}}
1151 void testConfigurationFilterNonConst2(void) {
1153 myScanf("%s", buffer
); // makes buffer tainted
1154 sanitizeCmd(buffer
); // removes taintedness
1155 system(buffer
); // no-warning
1158 void testConfigurationSinks(void) {
1159 int x
= mySource1();
1161 // expected-warning@-1 {{Untrusted data is passed to a user-defined sink}}
1162 mySink(1, x
, 2); // no-warning
1164 // expected-warning@-1 {{Untrusted data is passed to a user-defined sink}}
1167 int test_exec_like_functions() {
1168 char buf
[100] = {0};
1170 clang_analyzer_isTainted_char(buf
[0]); // expected-warning {{YES}}
1172 char *cleanArray
[] = {"ENV1=V1", "ENV2=V2", NULL
};
1173 char *taintedArray
[] = {buf
, "ENV2=V2", NULL
};
1174 clang_analyzer_isTainted_char(taintedArray
[0][0]); // expected-warning {{YES}}
1175 clang_analyzer_isTainted_char(*(char*)taintedArray
[0]); // expected-warning {{YES}}
1176 clang_analyzer_isTainted_char(*(char*)taintedArray
); // expected-warning {{NO}} We should have YES here.
1177 // FIXME: Above the triple pointer indirection will confuse the checker,
1178 // as we only check two levels. The results would be worse, if the tainted
1179 // subobject ("buf") would not be at the beginning of the enclosing object,
1180 // for the same reason.
1184 // Execute `path` with all arguments after `path` until a NULL pointer
1185 // and environment from `environ'.
1186 case 0: return execl("path", "arg0", "arg1", "arg2", NULL
); // no-warning
1187 case 1: return execl(buf
, "arg0", "arg1", "arg2", NULL
); // expected-warning {{Untrusted data is passed to a system call}}
1188 case 2: return execl("path", buf
, "arg1", "arg2", NULL
); // expected-warning {{Untrusted data is passed to a system call}}
1189 case 3: return execl("path", "arg0", buf
, "arg2", NULL
); // expected-warning {{Untrusted data is passed to a system call}}
1190 case 4: return execl("path", "arg0", "arg1", buf
, NULL
); // expected-warning {{Untrusted data is passed to a system call}}
1195 // Execute `path` with all arguments after `PATH` until a NULL pointer,
1196 // and the argument after that for environment.
1197 case 0: return execle("path", "arg0", "arg1", NULL
, cleanArray
); // no-warning
1198 case 1: return execle( buf
, "arg0", "arg1", NULL
, cleanArray
); // expected-warning {{Untrusted data is passed to a system call}}
1199 case 2: return execle("path", buf
, "arg1", NULL
, cleanArray
); // expected-warning {{Untrusted data is passed to a system call}}
1200 case 3: return execle("path", "arg0", buf
, NULL
, cleanArray
); // expected-warning {{Untrusted data is passed to a system call}}
1201 case 4: return execle("path", "arg0", "arg1", NULL
, buf
); // expected-warning {{Untrusted data is passed to a system call}}
1202 case 5: return execle("path", "arg0", "arg1", NULL
, taintedArray
); // FIXME: We might wanna have a report here.
1207 // Execute `file`, searching in the `PATH' environment variable if it
1208 // contains no slashes, with all arguments after `file` until a NULL
1209 // pointer and environment from `environ'.
1210 case 0: return execlp("file", "arg0", "arg1", "arg2", NULL
); // no-warning
1211 case 1: return execlp( buf
, "arg0", "arg1", "arg2", NULL
); // expected-warning {{Untrusted data is passed to a system call}}
1212 case 2: return execlp("file", buf
, "arg1", "arg2", NULL
); // expected-warning {{Untrusted data is passed to a system call}}
1213 case 3: return execlp("file", "arg0", buf
, "arg2", NULL
); // expected-warning {{Untrusted data is passed to a system call}}
1214 case 4: return execlp("file", "arg0", "arg1", buf
, NULL
); // expected-warning {{Untrusted data is passed to a system call}}
1219 // Execute `path` with arguments `ARGV` and environment from `environ'.
1220 case 0: return execv("path", /*argv=*/ cleanArray
); // no-warning
1221 case 1: return execv( buf
, /*argv=*/ cleanArray
); // expected-warning {{Untrusted data is passed to a system call}}
1222 case 2: return execv("path", /*argv=*/taintedArray
); // FIXME: We might wanna have a report here.
1227 // Replace the current process, executing `path` with arguments `ARGV`
1228 // and environment `ENVP`. `ARGV` and `ENVP` are terminated by NULL pointers.
1229 case 0: return execve("path", /*argv=*/ cleanArray
, /*envp=*/cleanArray
); // no-warning
1230 case 1: return execve( buf
, /*argv=*/ cleanArray
, /*envp=*/cleanArray
); // expected-warning {{Untrusted data is passed to a system call}}
1231 case 2: return execve("path", /*argv=*/taintedArray
, /*envp=*/cleanArray
); // FIXME: We might wanna have a report here.
1232 case 3: return execve("path", /*argv=*/cleanArray
, /*envp=*/taintedArray
); // FIXME: We might wanna have a report here.
1237 // Execute `file`, searching in the `PATH' environment variable if it
1238 // contains no slashes, with arguments `ARGV` and environment from `environ'.
1239 case 0: return execvp("file", /*argv=*/ cleanArray
); // no-warning
1240 case 1: return execvp( buf
, /*argv=*/ cleanArray
); // expected-warning {{Untrusted data is passed to a system call}}
1241 case 2: return execvp("file", /*argv=*/taintedArray
); // FIXME: We might wanna have a report here.
1247 // Execute `file`, searching in the `PATH' environment variable if it
1248 // contains no slashes, with arguments `ARGV` and environment `ENVP`.
1249 // `ARGV` and `ENVP` are terminated by NULL pointers.
1250 case 0: return execvpe("file", /*argv=*/ cleanArray
, /*envp=*/ cleanArray
); // no-warning
1251 case 1: return execvpe( buf
, /*argv=*/ cleanArray
, /*envp=*/ cleanArray
); // expected-warning {{Untrusted data is passed to a system call}}
1252 case 2: return execvpe("file", /*argv=*/taintedArray
, /*envp=*/ cleanArray
); // FIXME: We might wanna have a report here.
1253 case 3: return execvpe("file", /*argv=*/ cleanArray
, /*envp=*/taintedArray
); // FIXME: We might wanna have a report here.
1256 int cleanFD
= coin();
1258 scanf("%d", &taintedFD
);
1259 clang_analyzer_isTainted_int(taintedFD
); // expected-warning {{YES}}
1263 // Execute the file `FD` refers to, overlaying the running program image.
1264 // `ARGV` and `ENVP` are passed to the new program, as for `execve'.
1265 case 0: return fexecve( cleanFD
, /*argv=*/ cleanArray
, /*envp=*/ cleanArray
); // no-warning
1266 case 1: return fexecve(taintedFD
, /*argv=*/ cleanArray
, /*envp=*/ cleanArray
); // expected-warning {{Untrusted data is passed to a system call}}
1267 case 2: return fexecve( cleanFD
, /*argv=*/taintedArray
, /*envp=*/ cleanArray
); // FIXME: We might wanna have a report here.
1268 case 3: return fexecve( cleanFD
, /*argv=*/ cleanArray
, /*envp=*/taintedArray
); // FIXME: We might wanna have a report here.
1273 // Create a new stream connected to a pipe running the given `command`.
1274 case 0: return pclose(popen("command", /*mode=*/"r")); // no-warning
1275 case 1: return pclose(popen( buf
, /*mode=*/"r")); // expected-warning {{Untrusted data is passed to a system call}}
1276 case 2: return pclose(popen("command", /*mode=*/buf
)); // 'mode' is not a taint sink.
1281 // Execute the given line as a shell command.
1282 case 0: return system("command"); // no-warning
1283 case 1: return system( buf
); // expected-warning {{Untrusted data is passed to a system call}}
1289 void testUnknownFunction(void (*foo
)(void)) {
1293 void testProctitleFalseNegative(void) {
1295 fscanf(stdin
, "%79s", flag
);
1296 char *argv
[] = {"myapp", flag
};
1297 // FIXME: We should have a warning below: Untrusted data passed to sink.
1298 setproctitle_init(1, argv
, 0);
1301 void testProctitle2(char *real_argv
[]) {
1302 char *app
= getenv("APP_NAME");
1305 char *argv
[] = {app
, "--foobar"};
1306 setproctitle_init(1, argv
, 0); // expected-warning {{Untrusted data is passed to a user-defined sink}}
1307 setproctitle_init(1, real_argv
, argv
); // expected-warning {{Untrusted data is passed to a user-defined sink}}
1310 void testAcceptPropagates() {
1311 int listenSocket
= socket(2, 1, 6);
1312 clang_analyzer_isTainted_int(listenSocket
); // expected-warning {{YES}}
1313 int acceptSocket
= accept(listenSocket
, 0, 0);
1314 clang_analyzer_isTainted_int(acceptSocket
); // expected-warning {{YES}}