Main Content

Use of automatic variable as putenv-family function argument

putenv-family function argument not accessible outside its scope

Description

This defect occurs when the argument of a putenv-family function is a local variable with automatic duration.

Risk

The function putenv(char *string) inserts a pointer to its supplied argument into the environment array, instead of making a copy of the argument. If the argument is an automatic variable, its memory can be overwritten after the function containing the putenv() call returns. A subsequent call to getenv() from another function returns the address of an out-of-scope variable that cannot be dereferenced legally. This out-of-scope variable can cause environment variables to take on unexpected values, cause the program to stop responding, or allow arbitrary code execution vulnerabilities.

Fix

Use setenv()/unsetenv() to set and unset environment variables. Alternatively, use putenv-family function arguments with dynamically allocated memory, or, if your application has no reentrancy requirements, arguments with static duration. For example, a single thread execution with no recursion or interrupts does not require reentrancy. It cannot be called (reentered) during its execution.

Examples

expand all

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SIZE1024 1024

void func(int var)
{
    char env[SIZE1024];
    int retval = sprintf(env, "TEST=%s", var ? "1" : "0");
    if (retval <= 0) {
        /* Handle error */
    }
	/* Environment variable TEST is set using putenv().
	The argument passed to putenv is an automatic variable. */
    retval = putenv(env);   
    if (retval != 0) {
        /* Handle error */
    }
}
              

In this example, sprintf() stores the character string TEST=var in env. The value of the environment variable TEST is then set to var by using putenv(). Because env is an automatic variable, the value of TEST can change once func() returns.

Correction — Use static Variable for Argument of putenv()

Declare env as a static-duration variable. The memory location of env is not overwritten for the duration of the program, even after func() returns.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SIZE1024 1024 
void func(int var)
{
	/* static duration variable */
    static char env[SIZE1024]; 
    int retval = sprintf(env,"TEST=%s", var ? "1" : "0");
    if (retval <= 0) {
        /* Handle error */
    }
	
	/* Environment variable TEST is set using putenv() */
    retval=putenv(env);   
	if (retval != 0) {
        /* Handle error */
    }
}
Correction — Use setenv() to Set Environment Variable Value

To set the value of TEST to var, use setenv().

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SIZE1024 1024 

void func(int var)
{
	/* Environment variable TEST is set using setenv() */
    int retval = setenv("TEST", var ? "1" : "0", 1); 
	
    if (retval != 0) {
        /* Handle error */
    }
}

Result Information

Group: Static memory
Language: C | C++
Default: On for handwritten code, off for generated code
Command-Line Syntax: PUTENV_AUTO_VAR
Impact: High

Version History

Introduced in R2017b