taint-tester.c revision d3d8548e75f3fb6db53ed0927c1df30d78f4ce1d
1557a3829ebe0e36785b9a7679dc19dc67dbc7639Anna Zaks// RUN: %clang_cc1  -analyze -analyzer-checker=experimental.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);
7a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaks
8a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaks#define BUFSIZE 10
9a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaksint Buffer[BUFSIZE];
10a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaks
11dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaksstruct XYStruct {
12dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaks  int x;
135fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  int y;
145fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  char z;
15dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaks};
16dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaks
17dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaksvoid taintTracking(int x) {
18a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaks  int n;
19a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaks  int *addr = &Buffer[0];
20a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaks  scanf("%d", &n);
212135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  addr += n;// expected-warning + {{tainted}}
222135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  *addr = n; // expected-warning + {{tainted}}
23aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks
242135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  double tdiv = n / 30; // expected-warning+ {{tainted}}
252135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  char *loc_cast = (char *) n; // expected-warning +{{tainted}}
262135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  char tinc = tdiv++; // expected-warning + {{tainted}}
272135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int tincdec = (char)tinc--; // expected-warning+{{tainted}}
28aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks
29dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaks  // Tainted ptr arithmetic/array element address.
302135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int tprtarithmetic1 = *(addr+1); // expected-warning + {{tainted}}
31aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks
325fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  // Dereference.
335fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  int *ptr;
345fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  scanf("%p", &ptr);
352135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int ptrDeref = *ptr; // expected-warning + {{tainted}}
362135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int _ptrDeref = ptrDeref + 13; // expected-warning + {{tainted}}
375fc7def35ee858791e591d005b4ae343632ca931Anna Zaks
385fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  // Pointer arithmetic + dereferencing.
395fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  // FIXME: We fail to propagate the taint here because RegionStore does not
405fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  // handle ElementRegions with symbolic indexes.
412135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int addrDeref = *addr; // expected-warning + {{tainted}}
425fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  int _addrDeref = addrDeref;
435fc7def35ee858791e591d005b4ae343632ca931Anna Zaks
44dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaks  // Tainted struct address, casts.
45dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaks  struct XYStruct *xyPtr = 0;
46dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaks  scanf("%p", &xyPtr);
472135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  void *tXYStructPtr = xyPtr; // expected-warning + {{tainted}}
482135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  struct XYStruct *xyPtrCopy = tXYStructPtr; // expected-warning + {{tainted}}
492135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int ptrtx = xyPtr->x;// expected-warning + {{tainted}}
502135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int ptrty = xyPtr->y;// expected-warning + {{tainted}}
515fc7def35ee858791e591d005b4ae343632ca931Anna Zaks
525fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  // Taint on fields of a struct.
535fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  struct XYStruct xy = {2, 3, 11};
546fcd932dfd6835f70cc00d6f7c6789793f6d7b66Hans Wennborg  scanf("%d", &xy.y);
556fcd932dfd6835f70cc00d6f7c6789793f6d7b66Hans Wennborg  scanf("%d", &xy.x);
562135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int tx = xy.x; // expected-warning + {{tainted}}
575fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  int ty = xy.y; // FIXME: This should be tainted as well.
585fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  char ntz = xy.z;// no warning
591009ac715501a4fa1951d94722dcbe6ab30068f8Anna Zaks  // Now, scanf scans both.
601009ac715501a4fa1951d94722dcbe6ab30068f8Anna Zaks  scanf("%d %d", &xy.y, &xy.x);
612135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int ttx = xy.x; // expected-warning + {{tainted}}
622135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int tty = xy.y; // expected-warning + {{tainted}}
63a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaks}
64432a4558b8161c362efc319f8a38e074e74da201Anna Zaks
65432a4558b8161c362efc319f8a38e074e74da201Anna Zaksvoid BitwiseOp(int in, char inn) {
66432a4558b8161c362efc319f8a38e074e74da201Anna Zaks  // Taint on bitwise operations, integer to integer cast.
67432a4558b8161c362efc319f8a38e074e74da201Anna Zaks  int m;
68432a4558b8161c362efc319f8a38e074e74da201Anna Zaks  int x = 0;
69432a4558b8161c362efc319f8a38e074e74da201Anna Zaks  scanf("%d", &x);
702135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int y = (in << (x << in)) * 5;// expected-warning + {{tainted}}
71432a4558b8161c362efc319f8a38e074e74da201Anna Zaks  // The next line tests integer to integer cast.
722135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int z = y & inn; // expected-warning + {{tainted}}
732135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  if (y == 5) // expected-warning + {{tainted}}
742135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks    m = z | z;// expected-warning + {{tainted}}
75432a4558b8161c362efc319f8a38e074e74da201Anna Zaks  else
76432a4558b8161c362efc319f8a38e074e74da201Anna Zaks    m = inn;
772135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int mm = m; // expected-warning + {{tainted}}
78432a4558b8161c362efc319f8a38e074e74da201Anna Zaks}
7986277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks
8086277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks// Test getenv.
8186277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zakschar *getenv(const char *name);
8286277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaksvoid getenvTest(char *home) {
832135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  home = getenv("HOME"); // expected-warning + {{tainted}}
842135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  if (home != 0) { // expected-warning + {{tainted}}
852135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks      char d = home[0]; // expected-warning + {{tainted}}
8686277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks    }
8786277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks}
8886277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks
8986277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zakstypedef struct _FILE FILE;
9086277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaksextern FILE *stdin;
9186277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaksextern FILE *stdout;
9286277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaksextern FILE *stderr;
9386277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaksint fscanf(FILE *restrict stream, const char *restrict format, ...);
9486277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaksint fprintf(FILE *stream, const char *format, ...);
9586277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaksint fclose(FILE *stream);
9686277c5cd80d4f5911945fa207062aa9a44db8ffAnna ZaksFILE *fopen(const char *path, const char *mode);
9786277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks
9886277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaksint fscanfTest(void) {
9986277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks  FILE *fp;
10086277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks  char s[80];
10186277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks  int t;
10286277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks
10386277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks  // Check if stdin is treated as tainted.
10486277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks  fscanf(stdin, "%s %d", s, &t);
10586277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks  // Note, here, s is not tainted, but the data s points to is tainted.
10686277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks  char *ts = s;
1072135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  char tss = s[0]; // expected-warning + {{tainted}}
1082135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int tt = t; // expected-warning + {{tainted}}
1092135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  if((fp=fopen("test", "w")) == 0) // expected-warning + {{tainted}}
11086277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks    return 1;
1112135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  fprintf(fp, "%s %d", s, t); // expected-warning + {{tainted}}
1122135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  fclose(fp); // expected-warning + {{tainted}}
11386277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks
11486277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks  // Test fscanf and fopen.
1152135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  if((fp=fopen("test","r")) == 0) // expected-warning + {{tainted}}
11686277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks    return 1;
1172135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  fscanf(fp, "%s%d", s, &t); // expected-warning + {{tainted}}
1182135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  fprintf(stdout, "%s %d", s, t); // expected-warning + {{tainted}}
11986277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks  return 0;
12086277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks}
121d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks
122d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks// Check if we propagate taint from stdin when it's used in an assignment.
123d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaksvoid stdinTest1() {
124d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  int i;
125d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  fscanf(stdin, "%d", &i);
126d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  int j = i; // expected-warning + {{tainted}}
127d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks}
128d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaksvoid stdinTest2(FILE *pIn) {
129d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  FILE *p = stdin;
130d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  FILE *pp = p;
131d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  int ii;
132d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks
133d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  fscanf(pp, "%d", &ii);
134d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  int jj = ii;// expected-warning + {{tainted}}
135d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks
136d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  fscanf(p, "%d", &ii);
137d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  int jj2 = ii;// expected-warning + {{tainted}}
138d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks
139d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  ii = 3;
140d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  int jj3 = ii;// no warning
141d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks
142d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  p = pIn;
143d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  fscanf(p, "%d", &ii);
144d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  int jj4 = ii;// no warning
145d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks}
146d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks
147d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaksvoid stdinTest3() {
148d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  FILE **ppp = &stdin;
149d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  int iii;
150d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  fscanf(*ppp, "%d", &iii);
151d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  int jjj = iii;// expected-warning + {{tainted}}
152d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks}
153