1 // RUN: %clang_analyze_cc1 -Wno-int-to-pointer-cast -analyzer-checker=optin.taint,debug.TaintTest %s -verify 2 3 #include "Inputs/system-header-simulator.h" 4 5 #define BUFSIZE 10 6 int Buffer[BUFSIZE]; 7 8 struct XYStruct { 9 int x; 10 int y; 11 char z; 12 }; 13 14 void taintTracking(int x) { 15 int n; 16 int *addr = &Buffer[0]; 17 scanf("%d", &n); 18 addr += n;// expected-warning + {{tainted}} 19 *addr = n; // expected-warning + {{tainted}} 20 21 double tdiv = n / 30; // expected-warning+ {{tainted}} 22 char *loc_cast = (char *) n; // expected-warning +{{tainted}} 23 char tinc = tdiv++; // expected-warning + {{tainted}} 24 int tincdec = (char)tinc--; // expected-warning+{{tainted}} 25 26 // Tainted ptr arithmetic/array element address. 27 int tprtarithmetic1 = *(addr+1); // expected-warning + {{tainted}} 28 29 // Dereference. 30 int *ptr; 31 scanf("%p", &ptr); 32 int ptrDeref = *ptr; // expected-warning + {{tainted}} 33 int _ptrDeref = ptrDeref + 13; // expected-warning + {{tainted}} 34 35 // Pointer arithmetic + dereferencing. 36 // FIXME: We fail to propagate the taint here because RegionStore does not 37 // handle ElementRegions with symbolic indexes. 38 int addrDeref = *addr; // expected-warning + {{tainted}} 39 int _addrDeref = addrDeref; // expected-warning + {{tainted}} 40 41 // Tainted struct address, casts. 42 struct XYStruct *xyPtr = 0; 43 scanf("%p", &xyPtr); 44 void *tXYStructPtr = xyPtr; // expected-warning + {{tainted}} 45 struct XYStruct *xyPtrCopy = tXYStructPtr; // expected-warning + {{tainted}} 46 int ptrtx = xyPtr->x;// expected-warning + {{tainted}} 47 int ptrty = xyPtr->y;// expected-warning + {{tainted}} 48 49 // Taint on fields of a struct. 50 struct XYStruct xy = {2, 3, 11}; 51 scanf("%d", &xy.y); 52 scanf("%d", &xy.x); 53 int tx = xy.x; // expected-warning + {{tainted}} 54 int ty = xy.y; // FIXME: This should be tainted as well. 55 char ntz = xy.z;// no warning 56 // Now, scanf scans both. 57 scanf("%d %d", &xy.y, &xy.x); 58 int ttx = xy.x; // expected-warning + {{tainted}} 59 int tty = xy.y; // expected-warning + {{tainted}} 60 } 61 62 void BitwiseOp(int in, char inn, int zz) { 63 // Taint on bitwise operations, integer to integer cast. 64 int m; 65 int x = 0; 66 scanf("%d", &x); 67 int y = (in << (x << in)) * 5;// expected-warning + {{tainted}} 68 // The next line tests integer to integer cast. 69 int z = y & inn; // expected-warning + {{tainted}} 70 if (y == zz) { // expected-warning + {{tainted}} 71 m = z | z;// expected-warning + {{tainted}} 72 } 73 else 74 m = inn; 75 int mm = m; // expected-warning 1 {{tainted}} 76 } 77 78 // Test getenv. 79 char *getenv(const char *name); 80 void getenvTest(char *home) { 81 home = getenv("HOME"); // expected-warning + {{tainted}} 82 if (home != 0) { // expected-warning + {{tainted}} 83 char d = home[0]; // expected-warning + {{tainted}} 84 } 85 } 86 87 int fscanfTest(void) { 88 FILE *fp; 89 char s[80]; 90 int t; 91 92 // Check if stdin is treated as tainted. 93 fscanf(stdin, "%s %d", s, &t); 94 // Note, here, s is not tainted, but the data s points to is tainted. 95 char *ts = s; 96 char tss = s[0]; // expected-warning + {{tainted}} 97 int tt = t; // expected-warning + {{tainted}} 98 if((fp=fopen("test", "w")) == 0) // expected-warning + {{tainted}} 99 return 1; 100 fprintf(fp, "%s %d", s, t); // expected-warning + {{tainted}} 101 fclose(fp); // expected-warning + {{tainted}} 102 103 // Test fscanf and fopen. 104 if((fp=fopen("test","r")) == 0) // expected-warning + {{tainted}} 105 return 1; 106 fscanf(fp, "%s%d", s, &t); // expected-warning + {{tainted}} 107 fprintf(stdout, "%s %d", s, t); // expected-warning + {{tainted}} 108 return 0; 109 } 110 111 // Check if we propagate taint from stdin when it's used in an assignment. 112 void stdinTest1(void) { 113 int i; 114 fscanf(stdin, "%d", &i); 115 int j = i; // expected-warning + {{tainted}} 116 } 117 void stdinTest2(FILE *pIn) { 118 FILE *p = stdin; 119 FILE *pp = p; 120 int ii; 121 122 fscanf(pp, "%d", &ii); 123 int jj = ii;// expected-warning + {{tainted}} 124 125 fscanf(p, "%d", &ii);// expected-warning + {{tainted}} 126 int jj2 = ii;// expected-warning + {{tainted}} 127 128 ii = 3; 129 int jj3 = ii;// no warning 130 131 p = pIn; 132 fscanf(p, "%d", &ii); 133 int jj4 = ii;// no warning 134 } 135 136 void stdinTest3(void) { 137 FILE **ppp = &stdin; 138 int iii; 139 fscanf(*ppp, "%d", &iii); 140 int jjj = iii;// expected-warning + {{tainted}} 141 } 142 143 // Test that stdin does not get invalidated by calls. 144 void foo(void); 145 void stdinTest4(void) { 146 int i; 147 fscanf(stdin, "%d", &i); 148 foo(); 149 int j = i; // expected-warning + {{tainted}} 150 } 151 152 int getw(FILE *); 153 void getwTest(void) { 154 int i = getw(stdin); // expected-warning + {{tainted}} 155 } 156 157 ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict); 158 int printf(const char * __restrict, ...); 159 void free(void *ptr); 160 void getlineTest(void) { 161 FILE *fp; 162 char *line = 0; 163 size_t len = 0; 164 ssize_t read; 165 while ((read = getline(&line, &len, stdin)) != -1) { 166 printf("%s", line); // expected-warning + {{tainted}} 167 } 168 free(line); // expected-warning + {{tainted}} 169 } 170 171 // Test propagation functions - the ones that propagate taint from arguments to 172 // return value, ptr arguments. 173 174 int atoi(const char *nptr); 175 long atol(const char *nptr); 176 long long atoll(const char *nptr); 177 178 void atoiTest(void) { 179 char s[80]; 180 scanf("%s", s); 181 int d = atoi(s); // expected-warning + {{tainted}} 182 int td = d; // expected-warning + {{tainted}} 183 184 long l = atol(s); // expected-warning + {{tainted}} 185 int tl = l; // expected-warning + {{tainted}} 186 187 long long ll = atoll(s); // expected-warning + {{tainted}} 188 int tll = ll; // expected-warning + {{tainted}} 189 190 } 191 192 char *pointer1; 193 void *pointer2; 194 void noCrashTest(void) { 195 if (!*pointer1) { 196 __builtin___memcpy_chk(pointer2, pointer1, 0, 0); // no-crash 197 } 198 } 199 200 void builtin_overflow_test(void) { 201 int input, input2, res; 202 203 scanf("%d", &input); 204 scanf("%d", &input2); 205 206 if (__builtin_add_overflow(input, 10, &res)) // expected-warning + {{tainted}} 207 return; 208 209 if (__builtin_add_overflow(10, input, &res)) // expected-warning + {{tainted}} 210 return; 211 212 if (__builtin_add_overflow(input2, input, &res)) // expected-warning + {{tainted}} 213 return; 214 } 215