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