1 // RUN: %clang_analyze_cc1 \
2 // RUN:  -analyzer-checker=alpha.security.cert.pos.34c\
3 // RUN:  -verify %s
4 
5 // Examples from the CERT rule's page.
6 // https://wiki.sei.cmu.edu/confluence/x/6NYxBQ
7 
8 #include "../Inputs/system-header-simulator.h"
9 void free(void *memblock);
10 void *malloc(size_t size);
11 int putenv(char *);
12 int snprintf(char *str, size_t size, const char *format, ...);
13 
14 namespace test_auto_var_used_bad {
15 
16 int volatile_memory1(const char *var) {
17   char env[1024];
18   int retval = snprintf(env, sizeof(env), "TEST=%s", var);
19   if (retval < 0 || (size_t)retval >= sizeof(env)) {
20     /* Handle error */
21   }
22 
23   return putenv(env);
24   // expected-warning@-1 {{The 'putenv' function should not be called with arguments that have automatic storage}}
25 }
26 
27 } // namespace test_auto_var_used_bad
28 
29 namespace test_auto_var_used_good {
30 
31 int test_static(const char *var) {
32   static char env[1024];
33 
34   int retval = snprintf(env, sizeof(env), "TEST=%s", var);
35   if (retval < 0 || (size_t)retval >= sizeof(env)) {
36     /* Handle error */
37   }
38 
39   return putenv(env);
40 }
41 
42 int test_heap_memory(const char *var) {
43   static char *oldenv;
44   const char *env_format = "TEST=%s";
45   const size_t len = strlen(var) + strlen(env_format);
46   char *env = (char *)malloc(len);
47   if (env == NULL) {
48     return -1;
49   }
50   if (putenv(env) != 0) { // no-warning: env was dynamically allocated.
51     free(env);
52     return -1;
53   }
54   if (oldenv != NULL) {
55     free(oldenv); /* avoid memory leak */
56   }
57   oldenv = env;
58   return 0;
59 }
60 
61 } // namespace test_auto_var_used_good
62