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