Home | History | Annotate | Download | only in Analysis
      1 // RUN: %clang_cc1 -Wno-int-to-pointer-cast -analyze -analyzer-checker=alpha.security.taint,debug.TaintTest %s -verify
      2 
      3 #include "Inputs/system-header-simulator.h"
      4 
      5 #define BUFSIZE 10
      6 int Buffer[BUFSIZE];
      7 
      8 struct XYStruct {
      9   int x;
     10   int y;
     11   char z;
     12 };
     13 
     14 void 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 not
     37   // 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 warning
     56   // 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 
     62 void BitwiseOp(int in, char inn) {
     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 == 5) // expected-warning + {{tainted}}
     71     m = z | z;// expected-warning + {{tainted}}
     72   else
     73     m = inn;
     74   int mm = m; // expected-warning + {{tainted}}
     75 }
     76 
     77 // Test getenv.
     78 char *getenv(const char *name);
     79 void getenvTest(char *home) {
     80   home = getenv("HOME"); // expected-warning + {{tainted}}
     81   if (home != 0) { // expected-warning + {{tainted}}
     82       char d = home[0]; // expected-warning + {{tainted}}
     83     }
     84 }
     85 
     86 int fscanfTest(void) {
     87   FILE *fp;
     88   char s[80];
     89   int t;
     90 
     91   // Check if stdin is treated as tainted.
     92   fscanf(stdin, "%s %d", s, &t);
     93   // Note, here, s is not tainted, but the data s points to is tainted.
     94   char *ts = s;
     95   char tss = s[0]; // expected-warning + {{tainted}}
     96   int tt = t; // expected-warning + {{tainted}}
     97   if((fp=fopen("test", "w")) == 0) // expected-warning + {{tainted}}
     98     return 1;
     99   fprintf(fp, "%s %d", s, t); // expected-warning + {{tainted}}
    100   fclose(fp); // expected-warning + {{tainted}}
    101 
    102   // Test fscanf and fopen.
    103   if((fp=fopen("test","r")) == 0) // expected-warning + {{tainted}}
    104     return 1;
    105   fscanf(fp, "%s%d", s, &t); // expected-warning + {{tainted}}
    106   fprintf(stdout, "%s %d", s, t); // expected-warning + {{tainted}}
    107   return 0;
    108 }
    109 
    110 // Check if we propagate taint from stdin when it's used in an assignment.
    111 void stdinTest1() {
    112   int i;
    113   fscanf(stdin, "%d", &i);
    114   int j = i; // expected-warning + {{tainted}}
    115 }
    116 void stdinTest2(FILE *pIn) {
    117   FILE *p = stdin;
    118   FILE *pp = p;
    119   int ii;
    120 
    121   fscanf(pp, "%d", &ii);
    122   int jj = ii;// expected-warning + {{tainted}}
    123 
    124   fscanf(p, "%d", &ii);
    125   int jj2 = ii;// expected-warning + {{tainted}}
    126 
    127   ii = 3;
    128   int jj3 = ii;// no warning
    129 
    130   p = pIn;
    131   fscanf(p, "%d", &ii);
    132   int jj4 = ii;// no warning
    133 }
    134 
    135 void stdinTest3() {
    136   FILE **ppp = &stdin;
    137   int iii;
    138   fscanf(*ppp, "%d", &iii);
    139   int jjj = iii;// expected-warning + {{tainted}}
    140 }
    141 
    142 // Test that stdin does not get invalidated by calls.
    143 void foo();
    144 void stdinTest4() {
    145   int i;
    146   fscanf(stdin, "%d", &i);
    147   foo();
    148   int j = i; // expected-warning + {{tainted}}
    149 }
    150 
    151 int getw(FILE *);
    152 void getwTest() {
    153   int i = getw(stdin); // expected-warning + {{tainted}}
    154 }
    155 
    156 typedef long ssize_t;
    157 ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict);
    158 int  printf(const char * __restrict, ...);
    159 void free(void *ptr);
    160 void 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 to
    172 // return value, ptr arguments.
    173 
    174 int atoi(const char *nptr);
    175 long atol(const char *nptr);
    176 long long atoll(const char *nptr);
    177 
    178 void atoiTest() {
    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 
    192