CERT C: правило POS34-C

Не вызывайте putenv () с указателем на автоматическую переменную в качестве аргумента

Описание

Управляйте определением

Не вызывайте putenv () с указателем на автоматическую переменную в качестве аргумента. [1]

Примеры

развернуть все

Описание

Использование автоматической переменной как putenv - аргумент функции семейства происходит, когда аргумент putenv - функция семейства является локальной переменной с автоматической длительностью.

Риск

Функциональный putenv(char *string) вставляет указатель на свой переданный аргумент в массив среды, вместо того, чтобы делать копию аргумента. Если аргумент является автоматической переменной, ее память может быть перезаписана после того, как функция, содержащая вызов putenv(), возвращается. Последующий вызов getenv() от другой функции возвращает адрес переменной out-of-scope, которая не может быть разыменована по закону. Эта переменная out-of-scope может заставить переменные окружения брать неожиданные значения, заставлять программу прекращать отвечать или позволять произвольные уязвимости выполнения кода.

Фиксация

Используйте setenv()/unsetenv(), чтобы установить и сбросить переменные окружения. Также используйте putenv - аргументы функции семейства с динамически выделенной памятью, или, если ваше приложение не имеет никаких требований повторной входимости, аргументов со статической длительностью. Например, одно выполнение потока без рекурсии или прерываний не требует повторной входимости. Это не может быть названо (повторно введенное) во время своего выполнения.

Пример - автоматическая переменная в качестве аргумента 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);   
    if (retval != 0) {
        /* Handle error */
    }
}
              

В этом примере sprintf() хранит символьную строку TEST=var в env. Значение переменной окружения TEST затем установлено к var при помощи putenv(). Поскольку env является автоматической переменной, значение TEST может измениться, если func() возвращается.

Исправление — использует переменную static для аргумента putenv()

Объявите env как переменную статической длительности. Ячейка памяти env не перезаписывается на время программы, даже после того, как func() возвратится.

#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 */
    }
}

Исправление — использует setenv(), чтобы установить значение переменной окружения

Чтобы установить значение TEST к var, используйте 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 */
    }
}

Проверяйте информацию

Группа: правило 50. POSIX (POS)

Введенный в R2019a


[1]  Это программное обеспечение было создано MathWorks, включающим фрагменты: “Веб-сайт SEI CERT-C”, © 2017 Carnegie Mellon University, веб-сайт SEI CERT-C © 2017 Carnegie Mellon University”, CERT SEI C Кодирование Стандарта – Правил для Разработки безопасных, Надежных и Защищенных систем – 2 016 Выпусков”, © 2016 Carnegie Mellon University, and “CERT SEI Стандарт Кодирования C++ – Правил для Разработки безопасных, Надежных и Защищенных систем на C++ – 2 016 Выпусков” © 2016 Carnegie Mellon University, со специальным разрешением от его Института программной инженерии.

ЛЮБОЙ МАТЕРИАЛ УНИВЕРСИТЕТА КАРНЕГИ-МЕЛЛОН И/ИЛИ ЕГО ИНСТИТУТА ПРОГРАММНОЙ ИНЖЕНЕРИИ СОДЕРЖАЛ, ЗДЕСЬ ПРЕДОСТАВЛЯЕТСЯ НА ОСНОВЕ "ASIS". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ВЫРАЗИЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.

Это программное обеспечение и сопоставленная документация не были рассмотрены, ни являются подтвержденным Университетом Карнеги-Меллон или его Институтом программной инженерии.