taint-generic.c revision 9b0c749a20d0f7d0e63441d76baa15def3f37fdb
1// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.security.taint,experimental.security.ArrayBoundV2 -Wno-format-security -verify %s 2 3int scanf(const char *restrict format, ...); 4int getchar(void); 5 6typedef struct _FILE FILE; 7extern FILE *stdin; 8int fscanf(FILE *restrict stream, const char *restrict format, ...); 9int sprintf(char *str, const char *format, ...); 10void setproctitle(const char *fmt, ...); 11typedef __typeof(sizeof(int)) size_t; 12 13// Define string functions. Use builtin for some of them. They all default to 14// the processing in the taint checker. 15#define strcpy(dest, src) \ 16 ((__builtin_object_size(dest, 0) != -1ULL) \ 17 ? __builtin___strcpy_chk (dest, src, __builtin_object_size(dest, 1)) \ 18 : __inline_strcpy_chk(dest, src)) 19 20static char *__inline_strcpy_chk (char *dest, const char *src) { 21 return __builtin___strcpy_chk(dest, src, __builtin_object_size(dest, 1)); 22} 23char *stpcpy(char *restrict s1, const char *restrict s2); 24char *strncpy( char * destination, const char * source, size_t num ); 25char *strndup(const char *s, size_t n); 26 27#define BUFSIZE 10 28 29int Buffer[BUFSIZE]; 30void bufferScanfDirect(void) 31{ 32 int n; 33 scanf("%d", &n); 34 Buffer[n] = 1; // expected-warning {{Out of bound memory access }} 35} 36 37void bufferScanfArithmetic1(int x) { 38 int n; 39 scanf("%d", &n); 40 int m = (n - 3); 41 Buffer[m] = 1; // expected-warning {{Out of bound memory access }} 42} 43 44void bufferScanfArithmetic2(int x) { 45 int n; 46 scanf("%d", &n); 47 int m = 100 / (n + 3) * x; 48 Buffer[m] = 1; // expected-warning {{Out of bound memory access }} 49} 50 51void bufferScanfAssignment(int x) { 52 int n; 53 scanf("%d", &n); 54 int m; 55 if (x > 0) { 56 m = n; 57 Buffer[m] = 1; // expected-warning {{Out of bound memory access }} 58 } 59} 60 61void scanfArg() { 62 int t; 63 scanf("%d", t); // expected-warning {{conversion specifies type 'int *' but the argument has type 'int'}} 64} 65 66void bufferGetchar(int x) { 67 int m = getchar(); 68 Buffer[m] = 1; //expected-warning {{Out of bound memory access }} 69} 70 71void testUncontrolledFormatString(char **p) { 72 char s[80]; 73 fscanf(stdin, "%s", s); 74 char buf[128]; 75 sprintf(buf,s); // expected-warning {{Uncontrolled Format String}} 76 setproctitle(s, 3); // expected-warning {{Uncontrolled Format String}} 77 78 // Test taint propagation through strcpy and family. 79 char scpy[80]; 80 strcpy(scpy, s); 81 sprintf(buf,scpy); // expected-warning {{Uncontrolled Format String}} 82 83 stpcpy(*(++p), s); // this generates __inline. 84 setproctitle(*(p), 3); // expected-warning {{Uncontrolled Format String}} 85 86 char spcpy[80]; 87 stpcpy(spcpy, s); 88 setproctitle(spcpy, 3); // expected-warning {{Uncontrolled Format String}} 89 90 char *spcpyret; 91 spcpyret = stpcpy(spcpy, s); 92 setproctitle(spcpyret, 3); // expected-warning {{Uncontrolled Format String}} 93 94 char sncpy[80]; 95 strncpy(sncpy, s, 20); 96 setproctitle(sncpy, 3); // expected-warning {{Uncontrolled Format String}} 97 98 char *dup; 99 dup = strndup(s, 20); 100 setproctitle(dup, 3); // expected-warning {{Uncontrolled Format String}} 101 102} 103 104int system(const char *command); 105void testTaintSystemCall() { 106 char buffer[156]; 107 char addr[128]; 108 scanf("%s", addr); 109 system(addr); // expected-warning {{Tainted data passed to a system call}} 110 111 // Test that spintf transfers taint. 112 sprintf(buffer, "/bin/mail %s < /tmp/email", addr); 113 system(buffer); // expected-warning {{Tainted data passed to a system call}} 114} 115void testTaintSystemCall2() { 116 // Test that snpintf transfers taint. 117 char buffern[156]; 118 char addr[128]; 119 scanf("%s", addr); 120 __builtin_snprintf(buffern, 10, "/bin/mail %s < /tmp/email", addr); 121 system(buffern); // expected-warning {{Tainted data passed to a system call}} 122} 123void testTaintSystemCall3() { 124 char buffern2[156]; 125 int numt; 126 char addr[128]; 127 scanf("%s %d", addr, &numt); 128 __builtin_snprintf(buffern2, numt, "/bin/mail %s < /tmp/email", "abcd"); 129 system(buffern2); // expected-warning {{Tainted data passed to a system call}} 130} 131