taint-tester.c revision 9b29f4fe3d0600edf6ba00d48f2d4f2b1984f247
19b29f4fe3d0600edf6ba00d48f2d4f2b1984f247David Blaikie// RUN: %clang_cc1 -Wno-int-to-pointer-cast -analyze -analyzer-checker=alpha.security.taint,debug.TaintTest %s -verify
2a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaks
3efd6989f4644c8460854606e085fc69535054058Anna Zaks#include <stdarg.h>
4efd6989f4644c8460854606e085fc69535054058Anna Zaks
5a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaksint scanf(const char *restrict format, ...);
6a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaksint getchar(void);
7b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zakstypedef __typeof(sizeof(int)) size_t;
8a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaks
9a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaks#define BUFSIZE 10
10a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaksint Buffer[BUFSIZE];
11a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaks
12dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaksstruct XYStruct {
13dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaks  int x;
145fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  int y;
155fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  char z;
16dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaks};
17dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaks
18dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaksvoid taintTracking(int x) {
19a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaks  int n;
20a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaks  int *addr = &Buffer[0];
21a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaks  scanf("%d", &n);
222135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  addr += n;// expected-warning + {{tainted}}
232135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  *addr = n; // expected-warning + {{tainted}}
24aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks
252135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  double tdiv = n / 30; // expected-warning+ {{tainted}}
262135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  char *loc_cast = (char *) n; // expected-warning +{{tainted}}
272135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  char tinc = tdiv++; // expected-warning + {{tainted}}
282135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int tincdec = (char)tinc--; // expected-warning+{{tainted}}
29aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks
30dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaks  // Tainted ptr arithmetic/array element address.
312135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int tprtarithmetic1 = *(addr+1); // expected-warning + {{tainted}}
32aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks
335fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  // Dereference.
345fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  int *ptr;
355fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  scanf("%p", &ptr);
362135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int ptrDeref = *ptr; // expected-warning + {{tainted}}
372135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int _ptrDeref = ptrDeref + 13; // expected-warning + {{tainted}}
385fc7def35ee858791e591d005b4ae343632ca931Anna Zaks
395fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  // Pointer arithmetic + dereferencing.
405fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  // FIXME: We fail to propagate the taint here because RegionStore does not
415fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  // handle ElementRegions with symbolic indexes.
422135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int addrDeref = *addr; // expected-warning + {{tainted}}
434213e389d6f8fa96ab30eec0d932e4e3eee32997Ted Kremenek  int _addrDeref = addrDeref; // expected-warning + {{tainted}}
445fc7def35ee858791e591d005b4ae343632ca931Anna Zaks
45dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaks  // Tainted struct address, casts.
46dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaks  struct XYStruct *xyPtr = 0;
47dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaks  scanf("%p", &xyPtr);
482135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  void *tXYStructPtr = xyPtr; // expected-warning + {{tainted}}
492135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  struct XYStruct *xyPtrCopy = tXYStructPtr; // expected-warning + {{tainted}}
502135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int ptrtx = xyPtr->x;// expected-warning + {{tainted}}
512135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int ptrty = xyPtr->y;// expected-warning + {{tainted}}
525fc7def35ee858791e591d005b4ae343632ca931Anna Zaks
535fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  // Taint on fields of a struct.
545fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  struct XYStruct xy = {2, 3, 11};
556fcd932dfd6835f70cc00d6f7c6789793f6d7b66Hans Wennborg  scanf("%d", &xy.y);
566fcd932dfd6835f70cc00d6f7c6789793f6d7b66Hans Wennborg  scanf("%d", &xy.x);
572135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int tx = xy.x; // expected-warning + {{tainted}}
585fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  int ty = xy.y; // FIXME: This should be tainted as well.
595fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  char ntz = xy.z;// no warning
601009ac715501a4fa1951d94722dcbe6ab30068f8Anna Zaks  // Now, scanf scans both.
611009ac715501a4fa1951d94722dcbe6ab30068f8Anna Zaks  scanf("%d %d", &xy.y, &xy.x);
622135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int ttx = xy.x; // expected-warning + {{tainted}}
632135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int tty = xy.y; // expected-warning + {{tainted}}
64a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaks}
65432a4558b8161c362efc319f8a38e074e74da201Anna Zaks
66432a4558b8161c362efc319f8a38e074e74da201Anna Zaksvoid BitwiseOp(int in, char inn) {
67432a4558b8161c362efc319f8a38e074e74da201Anna Zaks  // Taint on bitwise operations, integer to integer cast.
68432a4558b8161c362efc319f8a38e074e74da201Anna Zaks  int m;
69432a4558b8161c362efc319f8a38e074e74da201Anna Zaks  int x = 0;
70432a4558b8161c362efc319f8a38e074e74da201Anna Zaks  scanf("%d", &x);
712135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int y = (in << (x << in)) * 5;// expected-warning + {{tainted}}
72432a4558b8161c362efc319f8a38e074e74da201Anna Zaks  // The next line tests integer to integer cast.
732135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int z = y & inn; // expected-warning + {{tainted}}
742135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  if (y == 5) // expected-warning + {{tainted}}
752135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks    m = z | z;// expected-warning + {{tainted}}
76432a4558b8161c362efc319f8a38e074e74da201Anna Zaks  else
77432a4558b8161c362efc319f8a38e074e74da201Anna Zaks    m = inn;
782135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int mm = m; // expected-warning + {{tainted}}
79432a4558b8161c362efc319f8a38e074e74da201Anna Zaks}
8086277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks
8186277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks// Test getenv.
8286277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zakschar *getenv(const char *name);
8386277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaksvoid getenvTest(char *home) {
842135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  home = getenv("HOME"); // expected-warning + {{tainted}}
852135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  if (home != 0) { // expected-warning + {{tainted}}
862135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks      char d = home[0]; // expected-warning + {{tainted}}
8786277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks    }
8886277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks}
8986277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks
9086277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zakstypedef struct _FILE FILE;
9186277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaksextern FILE *stdin;
9286277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaksextern FILE *stdout;
9386277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaksextern FILE *stderr;
9486277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaksint fscanf(FILE *restrict stream, const char *restrict format, ...);
9586277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaksint fprintf(FILE *stream, const char *format, ...);
9686277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaksint fclose(FILE *stream);
9786277c5cd80d4f5911945fa207062aa9a44db8ffAnna ZaksFILE *fopen(const char *path, const char *mode);
9886277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks
9986277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaksint fscanfTest(void) {
10086277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks  FILE *fp;
10186277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks  char s[80];
10286277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks  int t;
10386277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks
10486277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks  // Check if stdin is treated as tainted.
10586277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks  fscanf(stdin, "%s %d", s, &t);
10686277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks  // Note, here, s is not tainted, but the data s points to is tainted.
10786277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks  char *ts = s;
1082135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  char tss = s[0]; // expected-warning + {{tainted}}
1092135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int tt = t; // expected-warning + {{tainted}}
1102135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  if((fp=fopen("test", "w")) == 0) // expected-warning + {{tainted}}
11186277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks    return 1;
1122135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  fprintf(fp, "%s %d", s, t); // expected-warning + {{tainted}}
1132135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  fclose(fp); // expected-warning + {{tainted}}
11486277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks
11586277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks  // Test fscanf and fopen.
1162135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  if((fp=fopen("test","r")) == 0) // expected-warning + {{tainted}}
11786277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks    return 1;
1182135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  fscanf(fp, "%s%d", s, &t); // expected-warning + {{tainted}}
1192135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  fprintf(stdout, "%s %d", s, t); // expected-warning + {{tainted}}
12086277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks  return 0;
12186277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks}
122d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks
123d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks// Check if we propagate taint from stdin when it's used in an assignment.
124d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaksvoid stdinTest1() {
125d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  int i;
126d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  fscanf(stdin, "%d", &i);
127d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  int j = i; // expected-warning + {{tainted}}
128d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks}
129d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaksvoid stdinTest2(FILE *pIn) {
130d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  FILE *p = stdin;
131d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  FILE *pp = p;
132d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  int ii;
133d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks
134d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  fscanf(pp, "%d", &ii);
135d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  int jj = ii;// expected-warning + {{tainted}}
136d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks
137d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  fscanf(p, "%d", &ii);
138d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  int jj2 = ii;// expected-warning + {{tainted}}
139d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks
140d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  ii = 3;
141d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  int jj3 = ii;// no warning
142d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks
143d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  p = pIn;
144d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  fscanf(p, "%d", &ii);
145d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  int jj4 = ii;// no warning
146d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks}
147d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks
148d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaksvoid stdinTest3() {
149d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  FILE **ppp = &stdin;
150d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  int iii;
151d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  fscanf(*ppp, "%d", &iii);
152d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  int jjj = iii;// expected-warning + {{tainted}}
153d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks}
1549ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks
155273c3a3a3f009e26349ad9dfe67eaaa12db43af4Anna Zaks// Test that stdin does not get invalidated by calls.
156273c3a3a3f009e26349ad9dfe67eaaa12db43af4Anna Zaksvoid foo();
157273c3a3a3f009e26349ad9dfe67eaaa12db43af4Anna Zaksvoid stdinTest4() {
158273c3a3a3f009e26349ad9dfe67eaaa12db43af4Anna Zaks  int i;
159273c3a3a3f009e26349ad9dfe67eaaa12db43af4Anna Zaks  fscanf(stdin, "%d", &i);
160273c3a3a3f009e26349ad9dfe67eaaa12db43af4Anna Zaks  foo();
161273c3a3a3f009e26349ad9dfe67eaaa12db43af4Anna Zaks  int j = i; // expected-warning + {{tainted}}
162273c3a3a3f009e26349ad9dfe67eaaa12db43af4Anna Zaks}
163273c3a3a3f009e26349ad9dfe67eaaa12db43af4Anna Zaks
164b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaksint getw(FILE *);
165b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaksvoid getwTest() {
166b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  int i = getw(stdin); // expected-warning + {{tainted}}
167b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks}
168b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks
169b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zakstypedef long ssize_t;
170b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaksssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict);
171b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaksint  printf(const char * __restrict, ...);
172b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaksvoid free(void *ptr);
173b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaksvoid getlineTest(void) {
174b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  FILE *fp;
175b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  char *line = 0;
176b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  size_t len = 0;
177b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  ssize_t read;
178b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  while ((read = getline(&line, &len, stdin)) != -1) {
179b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks    printf("%s", line); // expected-warning + {{tainted}}
180b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  }
181b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  free(line); // expected-warning + {{tainted}}
182b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks}
183b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks
1849ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks// Test propagation functions - the ones that propagate taint from arguments to
1859ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks// return value, ptr arguments.
1869ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks
1879ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaksint atoi(const char *nptr);
1889ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zakslong atol(const char *nptr);
1899ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zakslong long atoll(const char *nptr);
1909ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks
1919ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaksvoid atoiTest() {
1929ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks  char s[80];
1939ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks  scanf("%s", s);
1949ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks  int d = atoi(s); // expected-warning + {{tainted}}
1959ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks  int td = d; // expected-warning + {{tainted}}
1965238474707de2c9a08465429bbb083be15b8e81aAnna Zaks
1972cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  long l = atol(s); // expected-warning + {{tainted}}
1985238474707de2c9a08465429bbb083be15b8e81aAnna Zaks  int tl = l; // expected-warning + {{tainted}}
1995238474707de2c9a08465429bbb083be15b8e81aAnna Zaks
2002cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  long long ll = atoll(s); // expected-warning + {{tainted}}
2015238474707de2c9a08465429bbb083be15b8e81aAnna Zaks  int tll = ll; // expected-warning + {{tainted}}
2025238474707de2c9a08465429bbb083be15b8e81aAnna Zaks
2039ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks}
2049ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks
205