xref: /llvm-project/clang/test/Analysis/cert/env34-c.c (revision b98a594977f25e555822e5ceef457f69c73cce45)
1 // RUN: %clang_analyze_cc1 \
2 // RUN:  -analyzer-checker=security.cert.env.InvalidPtr\
3 // RUN:  -analyzer-config security.cert.env.InvalidPtr:InvalidatingGetEnv=true \
4 // RUN:  -analyzer-output=text -verify -Wno-unused %s
5 
6 #include "../Inputs/system-header-simulator.h"
7 char *getenv(const char *name);
8 char *setlocale(int category, const char *locale);
9 char *strerror(int errnum);
10 
11 typedef struct {
12   char * field;
13 } lconv;
14 lconv *localeconv(void);
15 
16 typedef struct {
17 } tm;
18 char *asctime(const tm *timeptr);
19 
20 int strcmp(const char*, const char*);
21 extern void foo(char *e);
22 extern char* bar(void);
23 
24 
getenv_test1(void)25 void getenv_test1(void) {
26   char *p;
27 
28   p = getenv("VAR");
29   *p; // no-warning
30 
31   p = getenv("VAR2");
32   *p; // no-warning, getenv result was assigned to the same pointer
33 }
34 
getenv_test2(void)35 void getenv_test2(void) {
36   char *p, *p2;
37 
38   p = getenv("VAR");
39   // expected-note@-1{{previous function call was here}}
40   *p; // no-warning
41 
42   p2 = getenv("VAR2");
43   // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
44 
45   *p;
46   // expected-warning@-1{{dereferencing an invalid pointer}}
47   // expected-note@-2{{dereferencing an invalid pointer}}
48 }
49 
getenv_test3(void)50 void getenv_test3(void) {
51   char *p, *p2, *p3;
52 
53   p = getenv("VAR");
54   *p; // no-warning
55 
56   p = getenv("VAR2");
57   // expected-note@-1{{previous function call was here}}
58   p2 = getenv("VAR2");
59   // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
60 
61   p3 = getenv("VAR3");
62 
63   *p;
64   // expected-warning@-1{{dereferencing an invalid pointer}}
65   // expected-note@-2{{dereferencing an invalid pointer}}
66 }
67 
getenv_test4(void)68 void getenv_test4(void) {
69   char *p, *p2, *p3;
70 
71   p = getenv("VAR");
72   // expected-note@-1{{previous function call was here}}
73   p2 = getenv("VAR2");
74   // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
75   p3 = getenv("VAR3");
76 
77   *p;
78   // expected-warning@-1{{dereferencing an invalid pointer}}
79   // expected-note@-2{{dereferencing an invalid pointer}}
80 }
81 
getenv_test5(void)82 void getenv_test5(void) {
83   char *p, *p2, *p3;
84 
85   p = getenv("VAR");
86   p2 = getenv("VAR2");
87   // expected-note@-1{{previous function call was here}}
88   p3 = getenv("VAR3");
89   // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
90 
91   *p2;
92   // expected-warning@-1{{dereferencing an invalid pointer}}
93   // expected-note@-2{{dereferencing an invalid pointer}}
94 }
95 
getenv_test6(void)96 void getenv_test6(void) {
97   char *p, *p2;
98   p = getenv("VAR");
99   *p; // no-warning
100 
101   p = getenv("VAR2");
102   // expected-note@-1{{previous function call was here}}
103   *p; // no-warning
104 
105   p2 = getenv("VAR3");
106   // expected-note@-1{{previous function call was here}}
107   // expected-note@-2{{'getenv' call may invalidate the result of the previous 'getenv'}}
108 
109   *p;
110   // expected-warning@-1{{dereferencing an invalid pointer}}
111   // expected-note@-2{{dereferencing an invalid pointer}}
112 
113   *p2; // no-warning
114 
115   p = getenv("VAR4");
116   // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
117 
118   *p; // no-warning
119   *p2;
120   // expected-warning@-1{{dereferencing an invalid pointer}}
121   // expected-note@-2{{dereferencing an invalid pointer}}
122 }
123 
getenv_test7(void)124 void getenv_test7(void) {
125   char *p, *p2;
126   p = getenv("VAR");
127   // expected-note@-1{{previous function call was here}}
128   *p; // no-warning
129 
130   p2 = getenv("VAR2");
131   // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
132 
133   foo(p);
134   // expected-warning@-1{{use of invalidated pointer 'p' in a function call}}
135   // expected-note@-2{{use of invalidated pointer 'p' in a function call}}
136 }
137 
getenv_test8(void)138 void getenv_test8(void) {
139   static const char *array[] = {
140      0,
141      0,
142      "/var/tmp",
143      "/usr/tmp",
144      "/tmp",
145      "."
146   };
147 
148   if( !array[0] )
149   // expected-note@-1{{Taking true branch}}
150     array[0] = getenv("TEMPDIR");
151     // expected-note@-1{{previous function call was here}}
152 
153   if( !array[1] )
154   // expected-note@-1{{Taking true branch}}
155     array[1] = getenv("TMPDIR");
156   // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
157 
158   *array[0];
159   // expected-warning@-1{{dereferencing an invalid pointer}}
160   // expected-note@-2{{dereferencing an invalid pointer}}
161 }
162 
getenv_test9(void)163 void getenv_test9(void) {
164   char *p, *p2;
165   p = getenv("something");
166   p = bar();
167   p2 = getenv("something");
168   *p; // no-warning: p does not point to getenv anymore
169 }
170 
getenv_test10(void)171 void getenv_test10(void) {
172   strcmp(getenv("VAR1"), getenv("VAR2"));
173   // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
174   // expected-note@-2{{previous function call was here}}
175   // expected-warning@-3{{use of invalidated pointer 'getenv("VAR1")' in a function call}}
176   // expected-note@-4{{use of invalidated pointer 'getenv("VAR1")' in a function call}}
177 }
178 
dereference_pointer(char * a)179 void dereference_pointer(char* a) {
180   *a;
181   // expected-warning@-1{{dereferencing an invalid pointer}}
182   // expected-note@-2{{dereferencing an invalid pointer}}
183 }
184 
getenv_test11(void)185 void getenv_test11(void) {
186   char *p = getenv("VAR");
187   // expected-note@-1{{previous function call was here}}
188 
189   char *pp = getenv("VAR2");
190   // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
191 
192   dereference_pointer(p);
193   // expected-note@-1{{Calling 'dereference_pointer'}}
194 }
195 
getenv_test12(int flag1,int flag2)196 void getenv_test12(int flag1, int flag2) {
197   char *p = getenv("VAR");
198   // expected-note@-1{{previous function call was here}}
199 
200   if (flag1) {
201     // expected-note@-1{{Assuming 'flag1' is not equal to 0}}
202     // expected-note@-2{{Taking true branch}}
203     char *pp = getenv("VAR2");
204     // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
205   }
206 
207   if (flag2) {
208     // expected-note@-1{{Assuming 'flag2' is not equal to 0}}
209     // expected-note@-2{{Taking true branch}}
210     *p;
211     // expected-warning@-1{{dereferencing an invalid pointer}}
212     // expected-note@-2{{dereferencing an invalid pointer}}
213   }
214 }
215 
setlocale_test1(void)216 void setlocale_test1(void) {
217   char *p, *p2;
218   p = setlocale(0, "VAR");
219   *p; // no-warning
220 
221   p = setlocale(0, "VAR2");
222   // expected-note@-1{{previous function call was here}}
223   *p; // no-warning
224 
225   p2 = setlocale(0, "VAR3");
226   // expected-note@-1{{'setlocale' call may invalidate the result of the previous 'setlocale'}}
227 
228   *p;
229   // expected-warning@-1{{dereferencing an invalid pointer}}
230   // expected-note@-2{{dereferencing an invalid pointer}}
231 }
232 
setlocale_test2(int flag)233 void setlocale_test2(int flag) {
234   char *p, *p2;
235   p = setlocale(0, "VAR");
236   *p; // no-warning
237 
238   p = setlocale(0, "VAR2");
239   // expected-note@-1{{previous function call was here}}
240   *p; // no-warning
241 
242   if (flag) {
243     // expected-note@-1{{Assuming 'flag' is not equal to 0}}
244     // expected-note@-2{{Taking true branch}}
245     p2 = setlocale(0, "VAR3");
246     // expected-note@-1{{'setlocale' call may invalidate the result of the previous 'setlocale'}}
247   }
248 
249   *p;
250   // expected-warning@-1{{dereferencing an invalid pointer}}
251   // expected-note@-2{{dereferencing an invalid pointer}}
252 }
253 
strerror_test1(void)254 void strerror_test1(void) {
255   char *p, *p2;
256 
257   p = strerror(0);
258   *p; // no-warning
259 
260   p = strerror(1);
261   // expected-note@-1{{previous function call was here}}
262   *p; // no-warning
263 
264   p2 = strerror(2);
265   // expected-note@-1{{'strerror' call may invalidate the result of the previous 'strerror'}}
266 
267   *p;
268   // expected-warning@-1{{dereferencing an invalid pointer}}
269   // expected-note@-2{{dereferencing an invalid pointer}}
270 }
271 
strerror_test2(int errno)272 void strerror_test2(int errno) {
273   char *p, *p2;
274 
275   p = strerror(0);
276   *p; // no-warning
277 
278   p = strerror(1);
279   // expected-note@-1{{previous function call was here}}
280   *p; // no-warning
281 
282   if (0 == 1) {
283     // expected-note@-1{{0 is not equal to 1}}
284     // expected-note@-2{{Taking false branch}}
285     p2 = strerror(2);
286   }
287 
288   *p; // no-warning
289 
290   if (errno) {
291     // expected-note@-1{{Assuming 'errno' is not equal to 0}}
292     // expected-note@-2{{Taking true branch}}
293     p2 = strerror(errno);
294     // expected-note@-1{{'strerror' call may invalidate the result of the previous 'strerror'}}
295   }
296 
297   *p;
298   // expected-warning@-1{{dereferencing an invalid pointer}}
299   // expected-note@-2{{dereferencing an invalid pointer}}
300 }
301 
asctime_test(void)302 void asctime_test(void) {
303   const tm *t;
304   const tm *tt;
305 
306   char* p = asctime(t);
307   // expected-note@-1{{previous function call was here}}
308   char* pp = asctime(tt);
309   // expected-note@-1{{'asctime' call may invalidate the result of the previous 'asctime'}}
310 
311   *p;
312   // expected-warning@-1{{dereferencing an invalid pointer}}
313   // expected-note@-2{{dereferencing an invalid pointer}}
314 }
315 
localeconv_test1(void)316 void localeconv_test1(void) {
317   lconv *lc1 = localeconv();
318   // expected-note@-1{{previous function call was here}}
319   lconv *lc2 = localeconv();
320   // expected-note@-1{{'localeconv' call may invalidate the result of the previous 'localeconv'}}
321 
322   *lc1;
323   // expected-warning@-1{{dereferencing an invalid pointer}}
324   // expected-note@-2{{dereferencing an invalid pointer}}
325 }
326 
localeconv_test2(void)327 void localeconv_test2(void) {
328   // TODO: false negative
329   lconv *lc1 = localeconv();
330   lconv *lc2 = localeconv();
331   lc1->field;
332 }
333