Main Content

CERT C: Rule POS34-C

Do not call putenv() with a pointer to an automatic variable as the argument

Description

Rule Definition

Do not call putenv() with a pointer to an automatic variable as the argument.1

Polyspace Implementation

The rule checker checks for Use of automatic variable as putenv-family function argument.

Examples

expand all

Issue

Use of automatic variable as putenv-family function argument 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.

Example - Automatic Variable as Argument of putenv()
#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);    //Noncompliant
    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 */
    }
}

Check Information

Group: Rule 50. POSIX (POS)

Version History

Introduced in R2019a


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.