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