Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Wiki Markup
According to C99 \[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\]:

Wiki Markup
In a hosted environment, the main function receives a third argument, {{char \*envp\[\]}}, that points to a
NULL
 null-terminated array of pointers to {{char}}, each of which points to a string that provides information about the environment for this execution of the program.

However, modifying the environment by using the setenv() or putenv() functions, or by any other means, may cause the environment memory to be reallocated, with the result that envp now references an incorrect location. For example, when compiled with gcc-3.4.6 and run on Andrew Linux-2.6.16.29, the following code:

Code Block
extern char **environ;

int main(int argc, char *argv[], char *envp[]) { 
   printf("environ:  %p\n", environ); 
   printf("envp:     %p\n", envp); 
   setenv("MY_NEW_VAR", "new_value", 1);
   puts("--Added MY_NEW_VAR--");
   printf("environ:  %p\n", environ); 
   printf("envp:     %p\n", envp); 
}

Yields:

Code Block
% ./envp-environ
environ: 0xbf8656ec
envp:    0xbf8656ec
--Added MY_NEW_VAR--
environ: 0x804a008
envp:    0xbf8656ec

...

Code Block
bgColor#ffcccc
int main(int argc, char *argv[], char *envp[]) {
   setenv("MY_NEW_VAR", "new_value", 1);
   if (envp != NULL) {
      for (size_t i = 0; envp[i] != NULL; i++) {
         puts(envp[i]); 
      }
   }
   return 0;
}

Because envp no longer points to the current environment, this program has undefined behavior.

...

Code Block
bgColor#ccccff
extern char **environ;

int main(int argc, char *argv[]) {
   setenv("MY_NEW_VAR", "new_value", 1);
   if (environ != NULL) { 
      for (size_t i = 0; environ[i] != NULL; i++) {
         puts(environ[i]); 
      }
   }
   return 0;
}

Note: if you have a great deal of unsafe envp code, you could save time in your remediation by aliasing. Change:

...

Code Block
extern char **environ;
#define envp environ
 
main(int argc, char *argv[])

...