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