xref: /llvm-project/clang/test/Analysis/cert/env34-c.c (revision b98a594977f25e555822e5ceef457f69c73cce45)
1811b1736SZurab Tsinadze // RUN: %clang_analyze_cc1 \
2*b98a5949SEndre Fülöp // RUN:  -analyzer-checker=security.cert.env.InvalidPtr\
3*b98a5949SEndre Fülöp // RUN:  -analyzer-config security.cert.env.InvalidPtr:InvalidatingGetEnv=true \
4811b1736SZurab Tsinadze // RUN:  -analyzer-output=text -verify -Wno-unused %s
5811b1736SZurab Tsinadze 
6811b1736SZurab Tsinadze #include "../Inputs/system-header-simulator.h"
7811b1736SZurab Tsinadze char *getenv(const char *name);
8811b1736SZurab Tsinadze char *setlocale(int category, const char *locale);
9811b1736SZurab Tsinadze char *strerror(int errnum);
10811b1736SZurab Tsinadze 
11811b1736SZurab Tsinadze typedef struct {
12811b1736SZurab Tsinadze   char * field;
13811b1736SZurab Tsinadze } lconv;
14811b1736SZurab Tsinadze lconv *localeconv(void);
15811b1736SZurab Tsinadze 
16811b1736SZurab Tsinadze typedef struct {
17811b1736SZurab Tsinadze } tm;
18811b1736SZurab Tsinadze char *asctime(const tm *timeptr);
19811b1736SZurab Tsinadze 
20811b1736SZurab Tsinadze int strcmp(const char*, const char*);
21811b1736SZurab Tsinadze extern void foo(char *e);
220dd49a56SAaron Ballman extern char* bar(void);
23811b1736SZurab Tsinadze 
24811b1736SZurab Tsinadze 
getenv_test1(void)250dd49a56SAaron Ballman void getenv_test1(void) {
26811b1736SZurab Tsinadze   char *p;
27811b1736SZurab Tsinadze 
28811b1736SZurab Tsinadze   p = getenv("VAR");
29811b1736SZurab Tsinadze   *p; // no-warning
30811b1736SZurab Tsinadze 
31811b1736SZurab Tsinadze   p = getenv("VAR2");
32811b1736SZurab Tsinadze   *p; // no-warning, getenv result was assigned to the same pointer
33811b1736SZurab Tsinadze }
34811b1736SZurab Tsinadze 
getenv_test2(void)350dd49a56SAaron Ballman void getenv_test2(void) {
36811b1736SZurab Tsinadze   char *p, *p2;
37811b1736SZurab Tsinadze 
38811b1736SZurab Tsinadze   p = getenv("VAR");
39811b1736SZurab Tsinadze   // expected-note@-1{{previous function call was here}}
40811b1736SZurab Tsinadze   *p; // no-warning
41811b1736SZurab Tsinadze 
42811b1736SZurab Tsinadze   p2 = getenv("VAR2");
4387a55137SBrian Tracy   // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
44811b1736SZurab Tsinadze 
45811b1736SZurab Tsinadze   *p;
46811b1736SZurab Tsinadze   // expected-warning@-1{{dereferencing an invalid pointer}}
47811b1736SZurab Tsinadze   // expected-note@-2{{dereferencing an invalid pointer}}
48811b1736SZurab Tsinadze }
49811b1736SZurab Tsinadze 
getenv_test3(void)500dd49a56SAaron Ballman void getenv_test3(void) {
51811b1736SZurab Tsinadze   char *p, *p2, *p3;
52811b1736SZurab Tsinadze 
53811b1736SZurab Tsinadze   p = getenv("VAR");
54811b1736SZurab Tsinadze   *p; // no-warning
55811b1736SZurab Tsinadze 
56811b1736SZurab Tsinadze   p = getenv("VAR2");
57811b1736SZurab Tsinadze   // expected-note@-1{{previous function call was here}}
58811b1736SZurab Tsinadze   p2 = getenv("VAR2");
5987a55137SBrian Tracy   // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
60811b1736SZurab Tsinadze 
61811b1736SZurab Tsinadze   p3 = getenv("VAR3");
62811b1736SZurab Tsinadze 
63811b1736SZurab Tsinadze   *p;
64811b1736SZurab Tsinadze   // expected-warning@-1{{dereferencing an invalid pointer}}
65811b1736SZurab Tsinadze   // expected-note@-2{{dereferencing an invalid pointer}}
66811b1736SZurab Tsinadze }
67811b1736SZurab Tsinadze 
getenv_test4(void)680dd49a56SAaron Ballman void getenv_test4(void) {
69811b1736SZurab Tsinadze   char *p, *p2, *p3;
70811b1736SZurab Tsinadze 
71811b1736SZurab Tsinadze   p = getenv("VAR");
72811b1736SZurab Tsinadze   // expected-note@-1{{previous function call was here}}
73811b1736SZurab Tsinadze   p2 = getenv("VAR2");
7487a55137SBrian Tracy   // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
75811b1736SZurab Tsinadze   p3 = getenv("VAR3");
76811b1736SZurab Tsinadze 
77811b1736SZurab Tsinadze   *p;
78811b1736SZurab Tsinadze   // expected-warning@-1{{dereferencing an invalid pointer}}
79811b1736SZurab Tsinadze   // expected-note@-2{{dereferencing an invalid pointer}}
80811b1736SZurab Tsinadze }
81811b1736SZurab Tsinadze 
getenv_test5(void)820dd49a56SAaron Ballman void getenv_test5(void) {
83811b1736SZurab Tsinadze   char *p, *p2, *p3;
84811b1736SZurab Tsinadze 
85811b1736SZurab Tsinadze   p = getenv("VAR");
86811b1736SZurab Tsinadze   p2 = getenv("VAR2");
87811b1736SZurab Tsinadze   // expected-note@-1{{previous function call was here}}
88811b1736SZurab Tsinadze   p3 = getenv("VAR3");
8987a55137SBrian Tracy   // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
90811b1736SZurab Tsinadze 
91811b1736SZurab Tsinadze   *p2;
92811b1736SZurab Tsinadze   // expected-warning@-1{{dereferencing an invalid pointer}}
93811b1736SZurab Tsinadze   // expected-note@-2{{dereferencing an invalid pointer}}
94811b1736SZurab Tsinadze }
95811b1736SZurab Tsinadze 
getenv_test6(void)960dd49a56SAaron Ballman void getenv_test6(void) {
97811b1736SZurab Tsinadze   char *p, *p2;
98811b1736SZurab Tsinadze   p = getenv("VAR");
99811b1736SZurab Tsinadze   *p; // no-warning
100811b1736SZurab Tsinadze 
101811b1736SZurab Tsinadze   p = getenv("VAR2");
102811b1736SZurab Tsinadze   // expected-note@-1{{previous function call was here}}
103811b1736SZurab Tsinadze   *p; // no-warning
104811b1736SZurab Tsinadze 
105811b1736SZurab Tsinadze   p2 = getenv("VAR3");
106811b1736SZurab Tsinadze   // expected-note@-1{{previous function call was here}}
10787a55137SBrian Tracy   // expected-note@-2{{'getenv' call may invalidate the result of the previous 'getenv'}}
108811b1736SZurab Tsinadze 
109811b1736SZurab Tsinadze   *p;
110811b1736SZurab Tsinadze   // expected-warning@-1{{dereferencing an invalid pointer}}
111811b1736SZurab Tsinadze   // expected-note@-2{{dereferencing an invalid pointer}}
112811b1736SZurab Tsinadze 
113811b1736SZurab Tsinadze   *p2; // no-warning
114811b1736SZurab Tsinadze 
115811b1736SZurab Tsinadze   p = getenv("VAR4");
11687a55137SBrian Tracy   // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
117811b1736SZurab Tsinadze 
118811b1736SZurab Tsinadze   *p; // no-warning
119811b1736SZurab Tsinadze   *p2;
120811b1736SZurab Tsinadze   // expected-warning@-1{{dereferencing an invalid pointer}}
121811b1736SZurab Tsinadze   // expected-note@-2{{dereferencing an invalid pointer}}
122811b1736SZurab Tsinadze }
123811b1736SZurab Tsinadze 
getenv_test7(void)1240dd49a56SAaron Ballman void getenv_test7(void) {
125811b1736SZurab Tsinadze   char *p, *p2;
126811b1736SZurab Tsinadze   p = getenv("VAR");
127811b1736SZurab Tsinadze   // expected-note@-1{{previous function call was here}}
128811b1736SZurab Tsinadze   *p; // no-warning
129811b1736SZurab Tsinadze 
130811b1736SZurab Tsinadze   p2 = getenv("VAR2");
13187a55137SBrian Tracy   // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
132811b1736SZurab Tsinadze 
133811b1736SZurab Tsinadze   foo(p);
134811b1736SZurab Tsinadze   // expected-warning@-1{{use of invalidated pointer 'p' in a function call}}
135811b1736SZurab Tsinadze   // expected-note@-2{{use of invalidated pointer 'p' in a function call}}
136811b1736SZurab Tsinadze }
137811b1736SZurab Tsinadze 
getenv_test8(void)1380dd49a56SAaron Ballman void getenv_test8(void) {
139811b1736SZurab Tsinadze   static const char *array[] = {
140811b1736SZurab Tsinadze      0,
141811b1736SZurab Tsinadze      0,
142811b1736SZurab Tsinadze      "/var/tmp",
143811b1736SZurab Tsinadze      "/usr/tmp",
144811b1736SZurab Tsinadze      "/tmp",
145811b1736SZurab Tsinadze      "."
146811b1736SZurab Tsinadze   };
147811b1736SZurab Tsinadze 
148811b1736SZurab Tsinadze   if( !array[0] )
149811b1736SZurab Tsinadze   // expected-note@-1{{Taking true branch}}
150811b1736SZurab Tsinadze     array[0] = getenv("TEMPDIR");
151811b1736SZurab Tsinadze     // expected-note@-1{{previous function call was here}}
152811b1736SZurab Tsinadze 
153811b1736SZurab Tsinadze   if( !array[1] )
154811b1736SZurab Tsinadze   // expected-note@-1{{Taking true branch}}
155811b1736SZurab Tsinadze     array[1] = getenv("TMPDIR");
15687a55137SBrian Tracy   // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
157811b1736SZurab Tsinadze 
158811b1736SZurab Tsinadze   *array[0];
159811b1736SZurab Tsinadze   // expected-warning@-1{{dereferencing an invalid pointer}}
160811b1736SZurab Tsinadze   // expected-note@-2{{dereferencing an invalid pointer}}
161811b1736SZurab Tsinadze }
162811b1736SZurab Tsinadze 
getenv_test9(void)1630dd49a56SAaron Ballman void getenv_test9(void) {
164811b1736SZurab Tsinadze   char *p, *p2;
165811b1736SZurab Tsinadze   p = getenv("something");
166811b1736SZurab Tsinadze   p = bar();
167811b1736SZurab Tsinadze   p2 = getenv("something");
168811b1736SZurab Tsinadze   *p; // no-warning: p does not point to getenv anymore
169811b1736SZurab Tsinadze }
170811b1736SZurab Tsinadze 
getenv_test10(void)1710dd49a56SAaron Ballman void getenv_test10(void) {
172811b1736SZurab Tsinadze   strcmp(getenv("VAR1"), getenv("VAR2"));
17387a55137SBrian Tracy   // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
174811b1736SZurab Tsinadze   // expected-note@-2{{previous function call was here}}
175811b1736SZurab Tsinadze   // expected-warning@-3{{use of invalidated pointer 'getenv("VAR1")' in a function call}}
176811b1736SZurab Tsinadze   // expected-note@-4{{use of invalidated pointer 'getenv("VAR1")' in a function call}}
177811b1736SZurab Tsinadze }
178811b1736SZurab Tsinadze 
dereference_pointer(char * a)179811b1736SZurab Tsinadze void dereference_pointer(char* a) {
180811b1736SZurab Tsinadze   *a;
181811b1736SZurab Tsinadze   // expected-warning@-1{{dereferencing an invalid pointer}}
182811b1736SZurab Tsinadze   // expected-note@-2{{dereferencing an invalid pointer}}
183811b1736SZurab Tsinadze }
184811b1736SZurab Tsinadze 
getenv_test11(void)1850dd49a56SAaron Ballman void getenv_test11(void) {
186811b1736SZurab Tsinadze   char *p = getenv("VAR");
187811b1736SZurab Tsinadze   // expected-note@-1{{previous function call was here}}
188811b1736SZurab Tsinadze 
189811b1736SZurab Tsinadze   char *pp = getenv("VAR2");
19087a55137SBrian Tracy   // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
191811b1736SZurab Tsinadze 
192811b1736SZurab Tsinadze   dereference_pointer(p);
193811b1736SZurab Tsinadze   // expected-note@-1{{Calling 'dereference_pointer'}}
194811b1736SZurab Tsinadze }
195811b1736SZurab Tsinadze 
getenv_test12(int flag1,int flag2)196811b1736SZurab Tsinadze void getenv_test12(int flag1, int flag2) {
197811b1736SZurab Tsinadze   char *p = getenv("VAR");
198811b1736SZurab Tsinadze   // expected-note@-1{{previous function call was here}}
199811b1736SZurab Tsinadze 
200811b1736SZurab Tsinadze   if (flag1) {
201811b1736SZurab Tsinadze     // expected-note@-1{{Assuming 'flag1' is not equal to 0}}
202811b1736SZurab Tsinadze     // expected-note@-2{{Taking true branch}}
203811b1736SZurab Tsinadze     char *pp = getenv("VAR2");
20487a55137SBrian Tracy     // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
205811b1736SZurab Tsinadze   }
206811b1736SZurab Tsinadze 
207811b1736SZurab Tsinadze   if (flag2) {
208811b1736SZurab Tsinadze     // expected-note@-1{{Assuming 'flag2' is not equal to 0}}
209811b1736SZurab Tsinadze     // expected-note@-2{{Taking true branch}}
210811b1736SZurab Tsinadze     *p;
211811b1736SZurab Tsinadze     // expected-warning@-1{{dereferencing an invalid pointer}}
212811b1736SZurab Tsinadze     // expected-note@-2{{dereferencing an invalid pointer}}
213811b1736SZurab Tsinadze   }
214811b1736SZurab Tsinadze }
215811b1736SZurab Tsinadze 
setlocale_test1(void)2160dd49a56SAaron Ballman void setlocale_test1(void) {
217811b1736SZurab Tsinadze   char *p, *p2;
218811b1736SZurab Tsinadze   p = setlocale(0, "VAR");
219811b1736SZurab Tsinadze   *p; // no-warning
220811b1736SZurab Tsinadze 
221811b1736SZurab Tsinadze   p = setlocale(0, "VAR2");
222811b1736SZurab Tsinadze   // expected-note@-1{{previous function call was here}}
223811b1736SZurab Tsinadze   *p; // no-warning
224811b1736SZurab Tsinadze 
225811b1736SZurab Tsinadze   p2 = setlocale(0, "VAR3");
22687a55137SBrian Tracy   // expected-note@-1{{'setlocale' call may invalidate the result of the previous 'setlocale'}}
227811b1736SZurab Tsinadze 
228811b1736SZurab Tsinadze   *p;
229811b1736SZurab Tsinadze   // expected-warning@-1{{dereferencing an invalid pointer}}
230811b1736SZurab Tsinadze   // expected-note@-2{{dereferencing an invalid pointer}}
231811b1736SZurab Tsinadze }
232811b1736SZurab Tsinadze 
setlocale_test2(int flag)233811b1736SZurab Tsinadze void setlocale_test2(int flag) {
234811b1736SZurab Tsinadze   char *p, *p2;
235811b1736SZurab Tsinadze   p = setlocale(0, "VAR");
236811b1736SZurab Tsinadze   *p; // no-warning
237811b1736SZurab Tsinadze 
238811b1736SZurab Tsinadze   p = setlocale(0, "VAR2");
239811b1736SZurab Tsinadze   // expected-note@-1{{previous function call was here}}
240811b1736SZurab Tsinadze   *p; // no-warning
241811b1736SZurab Tsinadze 
242811b1736SZurab Tsinadze   if (flag) {
243811b1736SZurab Tsinadze     // expected-note@-1{{Assuming 'flag' is not equal to 0}}
244811b1736SZurab Tsinadze     // expected-note@-2{{Taking true branch}}
245811b1736SZurab Tsinadze     p2 = setlocale(0, "VAR3");
24687a55137SBrian Tracy     // expected-note@-1{{'setlocale' call may invalidate the result of the previous 'setlocale'}}
247811b1736SZurab Tsinadze   }
248811b1736SZurab Tsinadze 
249811b1736SZurab Tsinadze   *p;
250811b1736SZurab Tsinadze   // expected-warning@-1{{dereferencing an invalid pointer}}
251811b1736SZurab Tsinadze   // expected-note@-2{{dereferencing an invalid pointer}}
252811b1736SZurab Tsinadze }
253811b1736SZurab Tsinadze 
strerror_test1(void)2540dd49a56SAaron Ballman void strerror_test1(void) {
255811b1736SZurab Tsinadze   char *p, *p2;
256811b1736SZurab Tsinadze 
257811b1736SZurab Tsinadze   p = strerror(0);
258811b1736SZurab Tsinadze   *p; // no-warning
259811b1736SZurab Tsinadze 
260811b1736SZurab Tsinadze   p = strerror(1);
261811b1736SZurab Tsinadze   // expected-note@-1{{previous function call was here}}
262811b1736SZurab Tsinadze   *p; // no-warning
263811b1736SZurab Tsinadze 
264811b1736SZurab Tsinadze   p2 = strerror(2);
26587a55137SBrian Tracy   // expected-note@-1{{'strerror' call may invalidate the result of the previous 'strerror'}}
266811b1736SZurab Tsinadze 
267811b1736SZurab Tsinadze   *p;
268811b1736SZurab Tsinadze   // expected-warning@-1{{dereferencing an invalid pointer}}
269811b1736SZurab Tsinadze   // expected-note@-2{{dereferencing an invalid pointer}}
270811b1736SZurab Tsinadze }
271811b1736SZurab Tsinadze 
strerror_test2(int errno)272811b1736SZurab Tsinadze void strerror_test2(int errno) {
273811b1736SZurab Tsinadze   char *p, *p2;
274811b1736SZurab Tsinadze 
275811b1736SZurab Tsinadze   p = strerror(0);
276811b1736SZurab Tsinadze   *p; // no-warning
277811b1736SZurab Tsinadze 
278811b1736SZurab Tsinadze   p = strerror(1);
279811b1736SZurab Tsinadze   // expected-note@-1{{previous function call was here}}
280811b1736SZurab Tsinadze   *p; // no-warning
281811b1736SZurab Tsinadze 
282811b1736SZurab Tsinadze   if (0 == 1) {
283811b1736SZurab Tsinadze     // expected-note@-1{{0 is not equal to 1}}
284811b1736SZurab Tsinadze     // expected-note@-2{{Taking false branch}}
285811b1736SZurab Tsinadze     p2 = strerror(2);
286811b1736SZurab Tsinadze   }
287811b1736SZurab Tsinadze 
288811b1736SZurab Tsinadze   *p; // no-warning
289811b1736SZurab Tsinadze 
290811b1736SZurab Tsinadze   if (errno) {
291811b1736SZurab Tsinadze     // expected-note@-1{{Assuming 'errno' is not equal to 0}}
292811b1736SZurab Tsinadze     // expected-note@-2{{Taking true branch}}
293811b1736SZurab Tsinadze     p2 = strerror(errno);
29487a55137SBrian Tracy     // expected-note@-1{{'strerror' call may invalidate the result of the previous 'strerror'}}
295811b1736SZurab Tsinadze   }
296811b1736SZurab Tsinadze 
297811b1736SZurab Tsinadze   *p;
298811b1736SZurab Tsinadze   // expected-warning@-1{{dereferencing an invalid pointer}}
299811b1736SZurab Tsinadze   // expected-note@-2{{dereferencing an invalid pointer}}
300811b1736SZurab Tsinadze }
301811b1736SZurab Tsinadze 
asctime_test(void)3020dd49a56SAaron Ballman void asctime_test(void) {
303811b1736SZurab Tsinadze   const tm *t;
304811b1736SZurab Tsinadze   const tm *tt;
305811b1736SZurab Tsinadze 
306811b1736SZurab Tsinadze   char* p = asctime(t);
307811b1736SZurab Tsinadze   // expected-note@-1{{previous function call was here}}
308811b1736SZurab Tsinadze   char* pp = asctime(tt);
30987a55137SBrian Tracy   // expected-note@-1{{'asctime' call may invalidate the result of the previous 'asctime'}}
310811b1736SZurab Tsinadze 
311811b1736SZurab Tsinadze   *p;
312811b1736SZurab Tsinadze   // expected-warning@-1{{dereferencing an invalid pointer}}
313811b1736SZurab Tsinadze   // expected-note@-2{{dereferencing an invalid pointer}}
314811b1736SZurab Tsinadze }
315811b1736SZurab Tsinadze 
localeconv_test1(void)3160dd49a56SAaron Ballman void localeconv_test1(void) {
317811b1736SZurab Tsinadze   lconv *lc1 = localeconv();
318811b1736SZurab Tsinadze   // expected-note@-1{{previous function call was here}}
319811b1736SZurab Tsinadze   lconv *lc2 = localeconv();
32087a55137SBrian Tracy   // expected-note@-1{{'localeconv' call may invalidate the result of the previous 'localeconv'}}
321811b1736SZurab Tsinadze 
322811b1736SZurab Tsinadze   *lc1;
323811b1736SZurab Tsinadze   // expected-warning@-1{{dereferencing an invalid pointer}}
324811b1736SZurab Tsinadze   // expected-note@-2{{dereferencing an invalid pointer}}
325811b1736SZurab Tsinadze }
326811b1736SZurab Tsinadze 
localeconv_test2(void)3270dd49a56SAaron Ballman void localeconv_test2(void) {
328811b1736SZurab Tsinadze   // TODO: false negative
329811b1736SZurab Tsinadze   lconv *lc1 = localeconv();
330811b1736SZurab Tsinadze   lconv *lc2 = localeconv();
331811b1736SZurab Tsinadze   lc1->field;
332811b1736SZurab Tsinadze }
333