19b29f4fe3d0600edf6ba00d48f2d4f2b1984f247David Blaikie// RUN: %clang_cc1 -Wno-int-to-pointer-cast -analyze -analyzer-checker=alpha.security.taint,debug.TaintTest %s -verify
2a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaks
39a0b3c2f7c440c53b65bd1b085a7471d9f7ed490Jordan Rose#include "Inputs/system-header-simulator.h"
4a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaks
5a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaks#define BUFSIZE 10
6a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaksint Buffer[BUFSIZE];
7a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaks
8dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaksstruct XYStruct {
9dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaks  int x;
105fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  int y;
115fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  char z;
12dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaks};
13dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaks
14dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaksvoid taintTracking(int x) {
15a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaks  int n;
16a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaks  int *addr = &Buffer[0];
17a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaks  scanf("%d", &n);
182135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  addr += n;// expected-warning + {{tainted}}
192135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  *addr = n; // expected-warning + {{tainted}}
20aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks
212135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  double tdiv = n / 30; // expected-warning+ {{tainted}}
222135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  char *loc_cast = (char *) n; // expected-warning +{{tainted}}
232135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  char tinc = tdiv++; // expected-warning + {{tainted}}
242135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int tincdec = (char)tinc--; // expected-warning+{{tainted}}
25aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks
26dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaks  // Tainted ptr arithmetic/array element address.
272135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int tprtarithmetic1 = *(addr+1); // expected-warning + {{tainted}}
28aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks
295fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  // Dereference.
305fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  int *ptr;
315fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  scanf("%p", &ptr);
322135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int ptrDeref = *ptr; // expected-warning + {{tainted}}
332135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int _ptrDeref = ptrDeref + 13; // expected-warning + {{tainted}}
345fc7def35ee858791e591d005b4ae343632ca931Anna Zaks
355fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  // Pointer arithmetic + dereferencing.
365fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  // FIXME: We fail to propagate the taint here because RegionStore does not
375fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  // handle ElementRegions with symbolic indexes.
382135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int addrDeref = *addr; // expected-warning + {{tainted}}
394213e389d6f8fa96ab30eec0d932e4e3eee32997Ted Kremenek  int _addrDeref = addrDeref; // expected-warning + {{tainted}}
405fc7def35ee858791e591d005b4ae343632ca931Anna Zaks
41dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaks  // Tainted struct address, casts.
42dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaks  struct XYStruct *xyPtr = 0;
43dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaks  scanf("%p", &xyPtr);
442135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  void *tXYStructPtr = xyPtr; // expected-warning + {{tainted}}
452135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  struct XYStruct *xyPtrCopy = tXYStructPtr; // expected-warning + {{tainted}}
462135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int ptrtx = xyPtr->x;// expected-warning + {{tainted}}
472135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int ptrty = xyPtr->y;// expected-warning + {{tainted}}
485fc7def35ee858791e591d005b4ae343632ca931Anna Zaks
495fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  // Taint on fields of a struct.
505fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  struct XYStruct xy = {2, 3, 11};
516fcd932dfd6835f70cc00d6f7c6789793f6d7b66Hans Wennborg  scanf("%d", &xy.y);
526fcd932dfd6835f70cc00d6f7c6789793f6d7b66Hans Wennborg  scanf("%d", &xy.x);
532135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int tx = xy.x; // expected-warning + {{tainted}}
545fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  int ty = xy.y; // FIXME: This should be tainted as well.
555fc7def35ee858791e591d005b4ae343632ca931Anna Zaks  char ntz = xy.z;// no warning
561009ac715501a4fa1951d94722dcbe6ab30068f8Anna Zaks  // Now, scanf scans both.
571009ac715501a4fa1951d94722dcbe6ab30068f8Anna Zaks  scanf("%d %d", &xy.y, &xy.x);
582135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int ttx = xy.x; // expected-warning + {{tainted}}
592135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int tty = xy.y; // expected-warning + {{tainted}}
60a50b7ab5af79690855af68f1fff7897291ba9535Anna Zaks}
61432a4558b8161c362efc319f8a38e074e74da201Anna Zaks
62432a4558b8161c362efc319f8a38e074e74da201Anna Zaksvoid BitwiseOp(int in, char inn) {
63432a4558b8161c362efc319f8a38e074e74da201Anna Zaks  // Taint on bitwise operations, integer to integer cast.
64432a4558b8161c362efc319f8a38e074e74da201Anna Zaks  int m;
65432a4558b8161c362efc319f8a38e074e74da201Anna Zaks  int x = 0;
66432a4558b8161c362efc319f8a38e074e74da201Anna Zaks  scanf("%d", &x);
672135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int y = (in << (x << in)) * 5;// expected-warning + {{tainted}}
68432a4558b8161c362efc319f8a38e074e74da201Anna Zaks  // The next line tests integer to integer cast.
692135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int z = y & inn; // expected-warning + {{tainted}}
702135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  if (y == 5) // expected-warning + {{tainted}}
712135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks    m = z | z;// expected-warning + {{tainted}}
72432a4558b8161c362efc319f8a38e074e74da201Anna Zaks  else
73432a4558b8161c362efc319f8a38e074e74da201Anna Zaks    m = inn;
742135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int mm = m; // expected-warning + {{tainted}}
75432a4558b8161c362efc319f8a38e074e74da201Anna Zaks}
7686277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks
7786277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks// Test getenv.
7886277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zakschar *getenv(const char *name);
7986277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaksvoid getenvTest(char *home) {
802135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  home = getenv("HOME"); // expected-warning + {{tainted}}
812135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  if (home != 0) { // expected-warning + {{tainted}}
822135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks      char d = home[0]; // expected-warning + {{tainted}}
8386277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks    }
8486277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks}
8586277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks
8686277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaksint fscanfTest(void) {
8786277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks  FILE *fp;
8886277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks  char s[80];
8986277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks  int t;
9086277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks
9186277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks  // Check if stdin is treated as tainted.
9286277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks  fscanf(stdin, "%s %d", s, &t);
9386277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks  // Note, here, s is not tainted, but the data s points to is tainted.
9486277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks  char *ts = s;
952135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  char tss = s[0]; // expected-warning + {{tainted}}
962135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  int tt = t; // expected-warning + {{tainted}}
972135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  if((fp=fopen("test", "w")) == 0) // expected-warning + {{tainted}}
9886277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks    return 1;
992135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  fprintf(fp, "%s %d", s, t); // expected-warning + {{tainted}}
1002135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  fclose(fp); // expected-warning + {{tainted}}
10186277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks
10286277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks  // Test fscanf and fopen.
1032135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  if((fp=fopen("test","r")) == 0) // expected-warning + {{tainted}}
10486277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks    return 1;
1052135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  fscanf(fp, "%s%d", s, &t); // expected-warning + {{tainted}}
1062135ebb83179ee87910afdebc1bc091e17a7d1ebAnna Zaks  fprintf(stdout, "%s %d", s, t); // expected-warning + {{tainted}}
10786277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks  return 0;
10886277c5cd80d4f5911945fa207062aa9a44db8ffAnna Zaks}
109d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks
110d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks// Check if we propagate taint from stdin when it's used in an assignment.
111d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaksvoid stdinTest1() {
112d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  int i;
113d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  fscanf(stdin, "%d", &i);
114d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  int j = i; // expected-warning + {{tainted}}
115d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks}
116d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaksvoid stdinTest2(FILE *pIn) {
117d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  FILE *p = stdin;
118d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  FILE *pp = p;
119d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  int ii;
120d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks
121d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  fscanf(pp, "%d", &ii);
122d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  int jj = ii;// expected-warning + {{tainted}}
123d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks
124d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  fscanf(p, "%d", &ii);
125d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  int jj2 = ii;// expected-warning + {{tainted}}
126d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks
127d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  ii = 3;
128d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  int jj3 = ii;// no warning
129d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks
130d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  p = pIn;
131d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  fscanf(p, "%d", &ii);
132d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  int jj4 = ii;// no warning
133d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks}
134d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks
135d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaksvoid stdinTest3() {
136d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  FILE **ppp = &stdin;
137d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  int iii;
138d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  fscanf(*ppp, "%d", &iii);
139d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  int jjj = iii;// expected-warning + {{tainted}}
140d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks}
1419ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks
142273c3a3a3f009e26349ad9dfe67eaaa12db43af4Anna Zaks// Test that stdin does not get invalidated by calls.
143273c3a3a3f009e26349ad9dfe67eaaa12db43af4Anna Zaksvoid foo();
144273c3a3a3f009e26349ad9dfe67eaaa12db43af4Anna Zaksvoid stdinTest4() {
145273c3a3a3f009e26349ad9dfe67eaaa12db43af4Anna Zaks  int i;
146273c3a3a3f009e26349ad9dfe67eaaa12db43af4Anna Zaks  fscanf(stdin, "%d", &i);
147273c3a3a3f009e26349ad9dfe67eaaa12db43af4Anna Zaks  foo();
148273c3a3a3f009e26349ad9dfe67eaaa12db43af4Anna Zaks  int j = i; // expected-warning + {{tainted}}
149273c3a3a3f009e26349ad9dfe67eaaa12db43af4Anna Zaks}
150273c3a3a3f009e26349ad9dfe67eaaa12db43af4Anna Zaks
151b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaksint getw(FILE *);
152b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaksvoid getwTest() {
153b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  int i = getw(stdin); // expected-warning + {{tainted}}
154b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks}
155b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks
156b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zakstypedef long ssize_t;
157b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaksssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict);
158b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaksint  printf(const char * __restrict, ...);
159b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaksvoid free(void *ptr);
160b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaksvoid getlineTest(void) {
161b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  FILE *fp;
162b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  char *line = 0;
163b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  size_t len = 0;
164b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  ssize_t read;
165b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  while ((read = getline(&line, &len, stdin)) != -1) {
166b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks    printf("%s", line); // expected-warning + {{tainted}}
167b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  }
168b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  free(line); // expected-warning + {{tainted}}
169b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks}
170b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks
1719ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks// Test propagation functions - the ones that propagate taint from arguments to
1729ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks// return value, ptr arguments.
1739ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks
1749ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaksint atoi(const char *nptr);
1759ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zakslong atol(const char *nptr);
1769ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zakslong long atoll(const char *nptr);
1779ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks
1789ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaksvoid atoiTest() {
1799ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks  char s[80];
1809ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks  scanf("%s", s);
1819ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks  int d = atoi(s); // expected-warning + {{tainted}}
1829ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks  int td = d; // expected-warning + {{tainted}}
1835238474707de2c9a08465429bbb083be15b8e81aAnna Zaks
1842cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  long l = atol(s); // expected-warning + {{tainted}}
1855238474707de2c9a08465429bbb083be15b8e81aAnna Zaks  int tl = l; // expected-warning + {{tainted}}
1865238474707de2c9a08465429bbb083be15b8e81aAnna Zaks
1872cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  long long ll = atoll(s); // expected-warning + {{tainted}}
1885238474707de2c9a08465429bbb083be15b8e81aAnna Zaks  int tll = ll; // expected-warning + {{tainted}}
1895238474707de2c9a08465429bbb083be15b8e81aAnna Zaks
1909ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks}
1919ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks
192