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