xref: /llvm-project/clang/test/Analysis/cert/env34-c-cert-examples.c (revision b98a594977f25e555822e5ceef457f69c73cce45)
1 // Default options.
2 // RUN: %clang_analyze_cc1                                                      \
3 // RUN:  -analyzer-checker=core,security.cert.env.InvalidPtr                    \
4 // RUN:  -verify -Wno-unused %s
5 //
6 // Test the laxer handling of getenv function (this is the default).
7 // RUN: %clang_analyze_cc1                                                      \
8 // RUN:  -analyzer-checker=core,security.cert.env.InvalidPtr                    \
9 // RUN:  -analyzer-config security.cert.env.InvalidPtr:InvalidatingGetEnv=false \
10 // RUN:  -verify -Wno-unused %s
11 //
12 // Test the stricter handling of getenv function.
13 // RUN: %clang_analyze_cc1                                                      \
14 // RUN:  -analyzer-checker=core,security.cert.env.InvalidPtr                    \
15 // RUN:  -analyzer-config security.cert.env.InvalidPtr:InvalidatingGetEnv=true  \
16 // RUN:  -verify=expected,pedantic -Wno-unused %s
17 
18 #include "../Inputs/system-header-simulator.h"
19 char *getenv(const char *name);
20 int setenv(const char *name, const char *value, int overwrite);
21 int strcmp(const char*, const char*);
22 char *strdup(const char*);
23 void free(void *memblock);
24 void *malloc(size_t size);
25 
incorrect_usage_setenv_getenv_invalidation(void)26 void incorrect_usage_setenv_getenv_invalidation(void) {
27   char *tmpvar;
28   char *tempvar;
29 
30   tmpvar = getenv("TMP");
31 
32   if (!tmpvar)
33     return;
34 
35   setenv("TEMP", "", 1); //setenv can invalidate env
36 
37   if (!tmpvar)
38     return;
39 
40   if (strcmp(tmpvar, "") == 0) { // body of strcmp is unknown
41     // expected-warning@-1{{use of invalidated pointer 'tmpvar' in a function call}}
42   }
43 }
44 
incorrect_usage_double_getenv_invalidation(void)45 void incorrect_usage_double_getenv_invalidation(void) {
46   char *tmpvar;
47   char *tempvar;
48 
49   tmpvar = getenv("TMP");
50 
51   if (!tmpvar)
52     return;
53 
54   tempvar = getenv("TEMP"); //getenv should not invalidate env in non-pedantic mode
55 
56   if (!tempvar)
57     return;
58 
59   if (strcmp(tmpvar, tempvar) == 0) { // body of strcmp is unknown
60     // pedantic-warning@-1{{use of invalidated pointer 'tmpvar' in a function call}}
61   }
62 }
63 
correct_usage_1(void)64 void correct_usage_1(void) {
65   char *tmpvar;
66   char *tempvar;
67 
68   const char *temp = getenv("TMP");
69   if (temp != NULL) {
70     tmpvar = (char *)malloc(strlen(temp)+1);
71     if (tmpvar != NULL) {
72       strcpy(tmpvar, temp);
73     } else {
74       return;
75     }
76   } else {
77     return;
78   }
79 
80   temp = getenv("TEMP");
81   if (temp != NULL) {
82     tempvar = (char *)malloc(strlen(temp)+1);
83     if (tempvar != NULL) {
84       strcpy(tempvar, temp);
85     } else {
86       return;
87     }
88   } else {
89     return;
90   }
91 
92   if (strcmp(tmpvar, tempvar) == 0) {
93     printf("TMP and TEMP are the same.\n");
94   } else {
95     printf("TMP and TEMP are NOT the same.\n");
96   }
97   free(tmpvar);
98   free(tempvar);
99 }
100 
correct_usage_2(void)101 void correct_usage_2(void) {
102   char *tmpvar;
103   char *tempvar;
104 
105   const char *temp = getenv("TMP");
106   if (temp != NULL) {
107     tmpvar = strdup(temp);
108     if (tmpvar == NULL) {
109       return;
110     }
111   } else {
112     return;
113   }
114 
115   temp = getenv("TEMP");
116   if (temp != NULL) {
117     tempvar = strdup(temp);
118     if (tempvar == NULL) {
119       return;
120     }
121   } else {
122     return;
123   }
124 
125   if (strcmp(tmpvar, tempvar) == 0) {
126     printf("TMP and TEMP are the same.\n");
127   } else {
128     printf("TMP and TEMP are NOT the same.\n");
129   }
130   free(tmpvar);
131   tmpvar = NULL;
132   free(tempvar);
133   tempvar = NULL;
134 }
135