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