215 lines · c
1// RUN: %clang_analyze_cc1 -Wno-int-to-pointer-cast -analyzer-checker=optin.taint,debug.TaintTest %s -verify2 3#include "Inputs/system-header-simulator.h"4 5#define BUFSIZE 106int Buffer[BUFSIZE];7 8struct XYStruct {9 int x;10 int y;11 char z;12};13 14void taintTracking(int x) {15 int n;16 int *addr = &Buffer[0];17 scanf("%d", &n);18 addr += n;// expected-warning + {{tainted}}19 *addr = n; // expected-warning + {{tainted}}20 21 double tdiv = n / 30; // expected-warning+ {{tainted}}22 char *loc_cast = (char *) n; // expected-warning +{{tainted}}23 char tinc = tdiv++; // expected-warning + {{tainted}}24 int tincdec = (char)tinc--; // expected-warning+{{tainted}}25 26 // Tainted ptr arithmetic/array element address.27 int tprtarithmetic1 = *(addr+1); // expected-warning + {{tainted}}28 29 // Dereference.30 int *ptr;31 scanf("%p", &ptr);32 int ptrDeref = *ptr; // expected-warning + {{tainted}}33 int _ptrDeref = ptrDeref + 13; // expected-warning + {{tainted}}34 35 // Pointer arithmetic + dereferencing.36 // FIXME: We fail to propagate the taint here because RegionStore does not37 // handle ElementRegions with symbolic indexes.38 int addrDeref = *addr; // expected-warning + {{tainted}}39 int _addrDeref = addrDeref; // expected-warning + {{tainted}}40 41 // Tainted struct address, casts.42 struct XYStruct *xyPtr = 0;43 scanf("%p", &xyPtr);44 void *tXYStructPtr = xyPtr; // expected-warning + {{tainted}}45 struct XYStruct *xyPtrCopy = tXYStructPtr; // expected-warning + {{tainted}}46 int ptrtx = xyPtr->x;// expected-warning + {{tainted}}47 int ptrty = xyPtr->y;// expected-warning + {{tainted}}48 49 // Taint on fields of a struct.50 struct XYStruct xy = {2, 3, 11};51 scanf("%d", &xy.y);52 scanf("%d", &xy.x);53 int tx = xy.x; // expected-warning + {{tainted}}54 int ty = xy.y; // FIXME: This should be tainted as well.55 char ntz = xy.z;// no warning56 // Now, scanf scans both.57 scanf("%d %d", &xy.y, &xy.x);58 int ttx = xy.x; // expected-warning + {{tainted}}59 int tty = xy.y; // expected-warning + {{tainted}}60}61 62void BitwiseOp(int in, char inn, int zz) {63 // Taint on bitwise operations, integer to integer cast.64 int m;65 int x = 0;66 scanf("%d", &x);67 int y = (in << (x << in)) * 5;// expected-warning + {{tainted}}68 // The next line tests integer to integer cast.69 int z = y & inn; // expected-warning + {{tainted}}70 if (y == zz) { // expected-warning + {{tainted}}71 m = z | z;// expected-warning + {{tainted}}72 }73 else74 m = inn;75 int mm = m; // expected-warning 1 {{tainted}}76}77 78// Test getenv.79char *getenv(const char *name);80void getenvTest(char *home) {81 home = getenv("HOME"); // expected-warning + {{tainted}}82 if (home != 0) { // expected-warning + {{tainted}}83 char d = home[0]; // expected-warning + {{tainted}}84 }85}86 87int fscanfTest(void) {88 FILE *fp;89 char s[80];90 int t;91 92 // Check if stdin is treated as tainted.93 fscanf(stdin, "%s %d", s, &t);94 // Note, here, s is not tainted, but the data s points to is tainted.95 char *ts = s;96 char tss = s[0]; // expected-warning + {{tainted}}97 int tt = t; // expected-warning + {{tainted}}98 if((fp=fopen("test", "w")) == 0) // expected-warning + {{tainted}}99 return 1;100 fprintf(fp, "%s %d", s, t); // expected-warning + {{tainted}}101 fclose(fp); // expected-warning + {{tainted}}102 103 // Test fscanf and fopen.104 if((fp=fopen("test","r")) == 0) // expected-warning + {{tainted}}105 return 1;106 fscanf(fp, "%s%d", s, &t); // expected-warning + {{tainted}}107 fprintf(stdout, "%s %d", s, t); // expected-warning + {{tainted}}108 return 0;109}110 111// Check if we propagate taint from stdin when it's used in an assignment.112void stdinTest1(void) {113 int i;114 fscanf(stdin, "%d", &i);115 int j = i; // expected-warning + {{tainted}}116}117void stdinTest2(FILE *pIn) {118 FILE *p = stdin;119 FILE *pp = p;120 int ii;121 122 fscanf(pp, "%d", &ii);123 int jj = ii;// expected-warning + {{tainted}}124 125 fscanf(p, "%d", &ii);// expected-warning + {{tainted}}126 int jj2 = ii;// expected-warning + {{tainted}}127 128 ii = 3;129 int jj3 = ii;// no warning130 131 p = pIn;132 fscanf(p, "%d", &ii);133 int jj4 = ii;// no warning134}135 136void stdinTest3(void) {137 FILE **ppp = &stdin;138 int iii;139 fscanf(*ppp, "%d", &iii);140 int jjj = iii;// expected-warning + {{tainted}}141}142 143// Test that stdin does not get invalidated by calls.144void foo(void);145void stdinTest4(void) {146 int i;147 fscanf(stdin, "%d", &i);148 foo();149 int j = i; // expected-warning + {{tainted}}150}151 152int getw(FILE *);153void getwTest(void) {154 int i = getw(stdin); // expected-warning + {{tainted}}155}156 157ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict);158int printf(const char * __restrict, ...);159void free(void *ptr);160void getlineTest(void) {161 FILE *fp;162 char *line = 0;163 size_t len = 0;164 ssize_t read;165 while ((read = getline(&line, &len, stdin)) != -1) {166 printf("%s", line); // expected-warning + {{tainted}}167 }168 free(line); // expected-warning + {{tainted}}169}170 171// Test propagation functions - the ones that propagate taint from arguments to172// return value, ptr arguments.173 174int atoi(const char *nptr);175long atol(const char *nptr);176long long atoll(const char *nptr);177 178void atoiTest(void) {179 char s[80];180 scanf("%s", s);181 int d = atoi(s); // expected-warning + {{tainted}}182 int td = d; // expected-warning + {{tainted}}183 184 long l = atol(s); // expected-warning + {{tainted}}185 int tl = l; // expected-warning + {{tainted}}186 187 long long ll = atoll(s); // expected-warning + {{tainted}}188 int tll = ll; // expected-warning + {{tainted}}189 190}191 192char *pointer1;193void *pointer2;194void noCrashTest(void) {195 if (!*pointer1) {196 __builtin___memcpy_chk(pointer2, pointer1, 0, 0); // no-crash197 }198}199 200void builtin_overflow_test(void) {201 int input, input2, res;202 203 scanf("%d", &input);204 scanf("%d", &input2);205 206 if (__builtin_add_overflow(input, 10, &res)) // expected-warning + {{tainted}}207 return;208 209 if (__builtin_add_overflow(10, input, &res)) // expected-warning + {{tainted}}210 return;211 212 if (__builtin_add_overflow(input2, input, &res)) // expected-warning + {{tainted}}213 return;214}215