blob: 8c964e4ae2c50c111d1073ff6f28494c152e68e4 [file] [log] [blame]
Anna Zaks557a3822011-12-15 01:36:04 +00001// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.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);
7
8#define BUFSIZE 10
9int Buffer[BUFSIZE];
10
Anna Zaksdcf06fa2011-12-07 01:09:52 +000011struct XYStruct {
12 int x;
Anna Zaks5fc7def2011-12-08 22:38:43 +000013 int y;
14 char z;
Anna Zaksdcf06fa2011-12-07 01:09:52 +000015};
16
17void taintTracking(int x) {
Anna Zaksa50b7ab2011-12-05 18:58:01 +000018 int n;
19 int *addr = &Buffer[0];
20 scanf("%d", &n);
Anna Zaks2135ebb2011-12-15 02:28:16 +000021 addr += n;// expected-warning + {{tainted}}
22 *addr = n; // expected-warning + {{tainted}}
Anna Zaksaace9ef2011-12-06 23:12:27 +000023
Anna Zaks2135ebb2011-12-15 02:28:16 +000024 double tdiv = n / 30; // expected-warning+ {{tainted}}
25 char *loc_cast = (char *) n; // expected-warning +{{tainted}}
26 char tinc = tdiv++; // expected-warning + {{tainted}}
27 int tincdec = (char)tinc--; // expected-warning+{{tainted}}
Anna Zaksaace9ef2011-12-06 23:12:27 +000028
Anna Zaksdcf06fa2011-12-07 01:09:52 +000029 // Tainted ptr arithmetic/array element address.
Anna Zaks2135ebb2011-12-15 02:28:16 +000030 int tprtarithmetic1 = *(addr+1); // expected-warning + {{tainted}}
Anna Zaksaace9ef2011-12-06 23:12:27 +000031
Anna Zaks5fc7def2011-12-08 22:38:43 +000032 // Dereference.
33 int *ptr;
34 scanf("%p", &ptr);
Anna Zaks2135ebb2011-12-15 02:28:16 +000035 int ptrDeref = *ptr; // expected-warning + {{tainted}}
36 int _ptrDeref = ptrDeref + 13; // expected-warning + {{tainted}}
Anna Zaks5fc7def2011-12-08 22:38:43 +000037
38 // Pointer arithmetic + dereferencing.
39 // FIXME: We fail to propagate the taint here because RegionStore does not
40 // handle ElementRegions with symbolic indexes.
Anna Zaks2135ebb2011-12-15 02:28:16 +000041 int addrDeref = *addr; // expected-warning + {{tainted}}
Anna Zaks5fc7def2011-12-08 22:38:43 +000042 int _addrDeref = addrDeref;
43
Anna Zaksdcf06fa2011-12-07 01:09:52 +000044 // Tainted struct address, casts.
45 struct XYStruct *xyPtr = 0;
46 scanf("%p", &xyPtr);
Anna Zaks2135ebb2011-12-15 02:28:16 +000047 void *tXYStructPtr = xyPtr; // expected-warning + {{tainted}}
48 struct XYStruct *xyPtrCopy = tXYStructPtr; // expected-warning + {{tainted}}
49 int ptrtx = xyPtr->x;// expected-warning + {{tainted}}
50 int ptrty = xyPtr->y;// expected-warning + {{tainted}}
Anna Zaks5fc7def2011-12-08 22:38:43 +000051
52 // Taint on fields of a struct.
53 struct XYStruct xy = {2, 3, 11};
Hans Wennborg6fcd9322011-12-10 13:20:11 +000054 scanf("%d", &xy.y);
55 scanf("%d", &xy.x);
Anna Zaks2135ebb2011-12-15 02:28:16 +000056 int tx = xy.x; // expected-warning + {{tainted}}
Anna Zaks5fc7def2011-12-08 22:38:43 +000057 int ty = xy.y; // FIXME: This should be tainted as well.
58 char ntz = xy.z;// no warning
Anna Zaks1009ac72011-12-14 00:56:02 +000059 // Now, scanf scans both.
60 scanf("%d %d", &xy.y, &xy.x);
Anna Zaks2135ebb2011-12-15 02:28:16 +000061 int ttx = xy.x; // expected-warning + {{tainted}}
62 int tty = xy.y; // expected-warning + {{tainted}}
Anna Zaksa50b7ab2011-12-05 18:58:01 +000063}
Anna Zaks432a4552011-12-09 03:34:02 +000064
65void BitwiseOp(int in, char inn) {
66 // Taint on bitwise operations, integer to integer cast.
67 int m;
68 int x = 0;
69 scanf("%d", &x);
Anna Zaks2135ebb2011-12-15 02:28:16 +000070 int y = (in << (x << in)) * 5;// expected-warning + {{tainted}}
Anna Zaks432a4552011-12-09 03:34:02 +000071 // The next line tests integer to integer cast.
Anna Zaks2135ebb2011-12-15 02:28:16 +000072 int z = y & inn; // expected-warning + {{tainted}}
73 if (y == 5) // expected-warning + {{tainted}}
74 m = z | z;// expected-warning + {{tainted}}
Anna Zaks432a4552011-12-09 03:34:02 +000075 else
76 m = inn;
Anna Zaks2135ebb2011-12-15 02:28:16 +000077 int mm = m; // expected-warning + {{tainted}}
Anna Zaks432a4552011-12-09 03:34:02 +000078}
Anna Zaks86277c52011-12-14 18:34:17 +000079
80// Test getenv.
81char *getenv(const char *name);
82void getenvTest(char *home) {
Anna Zaks2135ebb2011-12-15 02:28:16 +000083 home = getenv("HOME"); // expected-warning + {{tainted}}
84 if (home != 0) { // expected-warning + {{tainted}}
85 char d = home[0]; // expected-warning + {{tainted}}
Anna Zaks86277c52011-12-14 18:34:17 +000086 }
87}
88
89typedef struct _FILE FILE;
90extern FILE *stdin;
91extern FILE *stdout;
92extern FILE *stderr;
93int fscanf(FILE *restrict stream, const char *restrict format, ...);
94int fprintf(FILE *stream, const char *format, ...);
95int fclose(FILE *stream);
96FILE *fopen(const char *path, const char *mode);
97
98int fscanfTest(void) {
99 FILE *fp;
100 char s[80];
101 int t;
102
103 // Check if stdin is treated as tainted.
104 fscanf(stdin, "%s %d", s, &t);
105 // Note, here, s is not tainted, but the data s points to is tainted.
106 char *ts = s;
Anna Zaks2135ebb2011-12-15 02:28:16 +0000107 char tss = s[0]; // expected-warning + {{tainted}}
108 int tt = t; // expected-warning + {{tainted}}
109 if((fp=fopen("test", "w")) == 0) // expected-warning + {{tainted}}
Anna Zaks86277c52011-12-14 18:34:17 +0000110 return 1;
Anna Zaks2135ebb2011-12-15 02:28:16 +0000111 fprintf(fp, "%s %d", s, t); // expected-warning + {{tainted}}
112 fclose(fp); // expected-warning + {{tainted}}
Anna Zaks86277c52011-12-14 18:34:17 +0000113
Anna Zaks86277c52011-12-14 18:34:17 +0000114 // Test fscanf and fopen.
Anna Zaks2135ebb2011-12-15 02:28:16 +0000115 if((fp=fopen("test","r")) == 0) // expected-warning + {{tainted}}
Anna Zaks86277c52011-12-14 18:34:17 +0000116 return 1;
Anna Zaks2135ebb2011-12-15 02:28:16 +0000117 fscanf(fp, "%s%d", s, &t); // expected-warning + {{tainted}}
118 fprintf(stdout, "%s %d", s, t); // expected-warning + {{tainted}}
Anna Zaks86277c52011-12-14 18:34:17 +0000119 return 0;
120}
Anna Zaksd3d85482011-12-16 18:28:50 +0000121
122// Check if we propagate taint from stdin when it's used in an assignment.
123void stdinTest1() {
124 int i;
125 fscanf(stdin, "%d", &i);
126 int j = i; // expected-warning + {{tainted}}
127}
128void stdinTest2(FILE *pIn) {
129 FILE *p = stdin;
130 FILE *pp = p;
131 int ii;
132
133 fscanf(pp, "%d", &ii);
134 int jj = ii;// expected-warning + {{tainted}}
135
136 fscanf(p, "%d", &ii);
137 int jj2 = ii;// expected-warning + {{tainted}}
138
139 ii = 3;
140 int jj3 = ii;// no warning
141
142 p = pIn;
143 fscanf(p, "%d", &ii);
144 int jj4 = ii;// no warning
145}
146
147void stdinTest3() {
148 FILE **ppp = &stdin;
149 int iii;
150 fscanf(*ppp, "%d", &iii);
151 int jjj = iii;// expected-warning + {{tainted}}
152}