blob: 7b0ab2a5fd34b28730c57e1b4c3c237c7985e51f [file] [log] [blame]
David Blaikie9b29f4f2012-10-16 18:53:14 +00001// RUN: %clang_cc1 -Wno-int-to-pointer-cast -analyze -analyzer-checker=alpha.security.taint,debug.TaintTest %s -verify
Anna Zaksa50b7ab2011-12-05 18:58:01 +00002
Anna Zaksefd69892011-12-14 00:56:18 +00003#include <stdarg.h>
4
Anna Zaksa50b7ab2011-12-05 18:58:01 +00005int scanf(const char *restrict format, ...);
6int getchar(void);
Anna Zaksb9ac30c2012-01-24 19:32:25 +00007typedef __typeof(sizeof(int)) size_t;
Anna Zaksa50b7ab2011-12-05 18:58:01 +00008
9#define BUFSIZE 10
10int Buffer[BUFSIZE];
11
Anna Zaksdcf06fa2011-12-07 01:09:52 +000012struct XYStruct {
13 int x;
Anna Zaks5fc7def2011-12-08 22:38:43 +000014 int y;
15 char z;
Anna Zaksdcf06fa2011-12-07 01:09:52 +000016};
17
18void taintTracking(int x) {
Anna Zaksa50b7ab2011-12-05 18:58:01 +000019 int n;
20 int *addr = &Buffer[0];
21 scanf("%d", &n);
Anna Zaks2135ebb2011-12-15 02:28:16 +000022 addr += n;// expected-warning + {{tainted}}
23 *addr = n; // expected-warning + {{tainted}}
Anna Zaksaace9ef2011-12-06 23:12:27 +000024
Anna Zaks2135ebb2011-12-15 02:28:16 +000025 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}}
Anna Zaksaace9ef2011-12-06 23:12:27 +000029
Anna Zaksdcf06fa2011-12-07 01:09:52 +000030 // Tainted ptr arithmetic/array element address.
Anna Zaks2135ebb2011-12-15 02:28:16 +000031 int tprtarithmetic1 = *(addr+1); // expected-warning + {{tainted}}
Anna Zaksaace9ef2011-12-06 23:12:27 +000032
Anna Zaks5fc7def2011-12-08 22:38:43 +000033 // Dereference.
34 int *ptr;
35 scanf("%p", &ptr);
Anna Zaks2135ebb2011-12-15 02:28:16 +000036 int ptrDeref = *ptr; // expected-warning + {{tainted}}
37 int _ptrDeref = ptrDeref + 13; // expected-warning + {{tainted}}
Anna Zaks5fc7def2011-12-08 22:38:43 +000038
39 // Pointer arithmetic + dereferencing.
40 // FIXME: We fail to propagate the taint here because RegionStore does not
41 // handle ElementRegions with symbolic indexes.
Anna Zaks2135ebb2011-12-15 02:28:16 +000042 int addrDeref = *addr; // expected-warning + {{tainted}}
Ted Kremenek4213e382012-05-08 21:49:54 +000043 int _addrDeref = addrDeref; // expected-warning + {{tainted}}
Anna Zaks5fc7def2011-12-08 22:38:43 +000044
Anna Zaksdcf06fa2011-12-07 01:09:52 +000045 // Tainted struct address, casts.
46 struct XYStruct *xyPtr = 0;
47 scanf("%p", &xyPtr);
Anna Zaks2135ebb2011-12-15 02:28:16 +000048 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}}
Anna Zaks5fc7def2011-12-08 22:38:43 +000052
53 // Taint on fields of a struct.
54 struct XYStruct xy = {2, 3, 11};
Hans Wennborg6fcd9322011-12-10 13:20:11 +000055 scanf("%d", &xy.y);
56 scanf("%d", &xy.x);
Anna Zaks2135ebb2011-12-15 02:28:16 +000057 int tx = xy.x; // expected-warning + {{tainted}}
Anna Zaks5fc7def2011-12-08 22:38:43 +000058 int ty = xy.y; // FIXME: This should be tainted as well.
59 char ntz = xy.z;// no warning
Anna Zaks1009ac72011-12-14 00:56:02 +000060 // Now, scanf scans both.
61 scanf("%d %d", &xy.y, &xy.x);
Anna Zaks2135ebb2011-12-15 02:28:16 +000062 int ttx = xy.x; // expected-warning + {{tainted}}
63 int tty = xy.y; // expected-warning + {{tainted}}
Anna Zaksa50b7ab2011-12-05 18:58:01 +000064}
Anna Zaks432a4552011-12-09 03:34:02 +000065
66void 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);
Anna Zaks2135ebb2011-12-15 02:28:16 +000071 int y = (in << (x << in)) * 5;// expected-warning + {{tainted}}
Anna Zaks432a4552011-12-09 03:34:02 +000072 // The next line tests integer to integer cast.
Anna Zaks2135ebb2011-12-15 02:28:16 +000073 int z = y & inn; // expected-warning + {{tainted}}
74 if (y == 5) // expected-warning + {{tainted}}
75 m = z | z;// expected-warning + {{tainted}}
Anna Zaks432a4552011-12-09 03:34:02 +000076 else
77 m = inn;
Anna Zaks2135ebb2011-12-15 02:28:16 +000078 int mm = m; // expected-warning + {{tainted}}
Anna Zaks432a4552011-12-09 03:34:02 +000079}
Anna Zaks86277c52011-12-14 18:34:17 +000080
81// Test getenv.
82char *getenv(const char *name);
83void getenvTest(char *home) {
Anna Zaks2135ebb2011-12-15 02:28:16 +000084 home = getenv("HOME"); // expected-warning + {{tainted}}
85 if (home != 0) { // expected-warning + {{tainted}}
86 char d = home[0]; // expected-warning + {{tainted}}
Anna Zaks86277c52011-12-14 18:34:17 +000087 }
88}
89
90typedef struct _FILE FILE;
91extern FILE *stdin;
92extern FILE *stdout;
93extern FILE *stderr;
94int fscanf(FILE *restrict stream, const char *restrict format, ...);
95int fprintf(FILE *stream, const char *format, ...);
96int fclose(FILE *stream);
97FILE *fopen(const char *path, const char *mode);
98
99int 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;
Anna Zaks2135ebb2011-12-15 02:28:16 +0000108 char tss = s[0]; // expected-warning + {{tainted}}
109 int tt = t; // expected-warning + {{tainted}}
110 if((fp=fopen("test", "w")) == 0) // expected-warning + {{tainted}}
Anna Zaks86277c52011-12-14 18:34:17 +0000111 return 1;
Anna Zaks2135ebb2011-12-15 02:28:16 +0000112 fprintf(fp, "%s %d", s, t); // expected-warning + {{tainted}}
113 fclose(fp); // expected-warning + {{tainted}}
Anna Zaks86277c52011-12-14 18:34:17 +0000114
Anna Zaks86277c52011-12-14 18:34:17 +0000115 // Test fscanf and fopen.
Anna Zaks2135ebb2011-12-15 02:28:16 +0000116 if((fp=fopen("test","r")) == 0) // expected-warning + {{tainted}}
Anna Zaks86277c52011-12-14 18:34:17 +0000117 return 1;
Anna Zaks2135ebb2011-12-15 02:28:16 +0000118 fscanf(fp, "%s%d", s, &t); // expected-warning + {{tainted}}
119 fprintf(stdout, "%s %d", s, t); // expected-warning + {{tainted}}
Anna Zaks86277c52011-12-14 18:34:17 +0000120 return 0;
121}
Anna Zaksd3d85482011-12-16 18:28:50 +0000122
123// Check if we propagate taint from stdin when it's used in an assignment.
124void stdinTest1() {
125 int i;
126 fscanf(stdin, "%d", &i);
127 int j = i; // expected-warning + {{tainted}}
128}
129void 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
148void stdinTest3() {
149 FILE **ppp = &stdin;
150 int iii;
151 fscanf(*ppp, "%d", &iii);
152 int jjj = iii;// expected-warning + {{tainted}}
153}
Anna Zaks9ffbe242011-12-17 00:26:34 +0000154
Anna Zaks273c3a32012-01-04 23:54:04 +0000155// Test that stdin does not get invalidated by calls.
156void foo();
157void stdinTest4() {
158 int i;
159 fscanf(stdin, "%d", &i);
160 foo();
161 int j = i; // expected-warning + {{tainted}}
162}
163
Anna Zaksb9ac30c2012-01-24 19:32:25 +0000164int getw(FILE *);
165void getwTest() {
166 int i = getw(stdin); // expected-warning + {{tainted}}
167}
168
169typedef long ssize_t;
170ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict);
171int printf(const char * __restrict, ...);
172void free(void *ptr);
173void 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
Anna Zaks9ffbe242011-12-17 00:26:34 +0000184// Test propagation functions - the ones that propagate taint from arguments to
185// return value, ptr arguments.
186
187int atoi(const char *nptr);
Anna Zaks9ffbe242011-12-17 00:26:34 +0000188long atol(const char *nptr);
189long long atoll(const char *nptr);
190
191void atoiTest() {
192 char s[80];
193 scanf("%s", s);
194 int d = atoi(s); // expected-warning + {{tainted}}
195 int td = d; // expected-warning + {{tainted}}
Anna Zaks52384742011-12-17 00:30:16 +0000196
Anna Zaks2cbe7912011-12-20 22:35:30 +0000197 long l = atol(s); // expected-warning + {{tainted}}
Anna Zaks52384742011-12-17 00:30:16 +0000198 int tl = l; // expected-warning + {{tainted}}
199
Anna Zaks2cbe7912011-12-20 22:35:30 +0000200 long long ll = atoll(s); // expected-warning + {{tainted}}
Anna Zaks52384742011-12-17 00:30:16 +0000201 int tll = ll; // expected-warning + {{tainted}}
202
Anna Zaks9ffbe242011-12-17 00:26:34 +0000203}
204