taint-tester.c revision 1009ac715501a4fa1951d94722dcbe6ab30068f8
1// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.security.taint,debug.TaintTest -verify %s 2 3int scanf(const char *restrict format, ...); 4int getchar(void); 5 6#define BUFSIZE 10 7int Buffer[BUFSIZE]; 8 9struct XYStruct { 10 int x; 11 int y; 12 char z; 13}; 14 15void taintTracking(int x) { 16 int n; 17 int *addr = &Buffer[0]; 18 scanf("%d", &n); 19 addr += n;// expected-warning 2 {{tainted}} 20 *addr = n; // expected-warning 3 {{tainted}} 21 22 double tdiv = n / 30; // expected-warning 3 {{tainted}} 23 char *loc_cast = (char *) n; // expected-warning {{tainted}} 24 char tinc = tdiv++; // expected-warning {{tainted}} 25 int tincdec = (char)tinc--; // expected-warning 2 {{tainted}} 26 27 // Tainted ptr arithmetic/array element address. 28 int tprtarithmetic1 = *(addr+1); // expected-warning 2 {{tainted}} 29 30 // Dereference. 31 int *ptr; 32 scanf("%p", &ptr); 33 int ptrDeref = *ptr; // expected-warning 2 {{tainted}} 34 int _ptrDeref = ptrDeref + 13; // expected-warning 2 {{tainted}} 35 36 // Pointer arithmetic + dereferencing. 37 // FIXME: We fail to propagate the taint here because RegionStore does not 38 // handle ElementRegions with symbolic indexes. 39 int addrDeref = *addr; // expected-warning {{tainted}} 40 int _addrDeref = addrDeref; 41 42 // Tainted struct address, casts. 43 struct XYStruct *xyPtr = 0; 44 scanf("%p", &xyPtr); 45 void *tXYStructPtr = xyPtr; // expected-warning 2 {{tainted}} 46 struct XYStruct *xyPtrCopy = tXYStructPtr; // expected-warning 2 {{tainted}} 47 int ptrtx = xyPtr->x;// expected-warning 2 {{tainted}} 48 int ptrty = xyPtr->y;// expected-warning 2 {{tainted}} 49 50 // Taint on fields of a struct. 51 struct XYStruct xy = {2, 3, 11}; 52 scanf("%d", &xy.y); 53 scanf("%d", &xy.x); 54 int tx = xy.x; // expected-warning {{tainted}} 55 int ty = xy.y; // FIXME: This should be tainted as well. 56 char ntz = xy.z;// no warning 57 // Now, scanf scans both. 58 scanf("%d %d", &xy.y, &xy.x); 59 int ttx = xy.x; // expected-warning {{tainted}} 60 int tty = xy.y; // expected-warning {{tainted}} 61} 62 63void BitwiseOp(int in, char inn) { 64 // Taint on bitwise operations, integer to integer cast. 65 int m; 66 int x = 0; 67 scanf("%d", &x); 68 int y = (in << (x << in)) * 5;// expected-warning 4 {{tainted}} 69 // The next line tests integer to integer cast. 70 int z = y & inn; // expected-warning 2 {{tainted}} 71 if (y == 5) // expected-warning 2 {{tainted}} 72 m = z | z;// expected-warning 4 {{tainted}} 73 else 74 m = inn; 75 int mm = m; // expected-warning {{tainted}} 76} 77 78// Test getenv. 79char *getenv(const char *name); 80void getenvTest(char *home) { 81 home = getenv("HOME"); // expected-warning 2 {{tainted}} 82 if (home != 0) { // expected-warning 2 {{tainted}} 83 char d = home[0]; // expected-warning 2 {{tainted}} 84 } 85} 86 87struct _IO_FILE { 88 unsigned fakeField1; 89 char fakeField2; 90}; 91typedef struct _IO_FILE FILE; 92extern struct _IO_FILE *stdin; 93extern struct _IO_FILE *stdout; 94extern struct _IO_FILE *stderr; 95int fscanf(FILE *restrict stream, const char *restrict format, ...); 96int fprintf(FILE *stream, const char *format, ...); 97int fclose(FILE *stream); 98FILE *fopen(const char *path, const char *mode); 99 100int fscanfTest(void) { 101 FILE *fp; 102 char s[80]; 103 int t; 104 105 if((fp=fopen("test", "w")) == 0) // expected-warning 3 {{tainted}} 106 return 1; 107 // TODO: Have to mark stdin as tainted. 108 fscanf(stdin, "%s%d", s, &t); 109 fprintf(fp, "%s %d", s, t); // expected-warning 1 {{tainted}} 110 fclose(fp); // expected-warning 1 {{tainted}} 111 112 if((fp=fopen("test","r")) == 0) // expected-warning 3 {{tainted}} 113 return 1; 114 fscanf(fp, "%s%d", s, &t); // expected-warning 1 {{tainted}} 115 fprintf(stdout, "%s %d", s, t); // expected-warning 1 {{tainted}} 116 return 0; 117} 118