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