CERT C: Rule ENV31-C

Не используйте указатель среды после операции, которая может делать недействительным его

Описание

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

Не используйте указатель среды после операции, которая может делать недействительным it.[1]

Реализация Polyspace

Это средство проверки проверяет на указатель Среды, делаемый недействительным предыдущей операцией.

Примеры

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

Проблема

Указатель среды, делаемый недействительным предыдущей операцией, происходит, когда вы используете третий аргумент основных () в размещенной среде, чтобы получить доступ к среде после того, как операция изменяет среду. В размещенной среде много реализаций C поддерживают нестандартный синтаксис:

main (int argc, char *argv[], char *envp[])
Вызов setenv или putenv функция семейства изменяет среду, на которую указывает *envp.

Риск

Когда вы изменяете среду через вызов setenv или putenv функция семейства, память среды может потенциально быть перераспределена. Размещенный указатель среды не обновляется и может указать на неправильное местоположение. Вызов этого указателя может возвратить неожиданные результаты или вызвать аварийное завершение программы.

Фиксация

Не используйте размещенный указатель среды. Вместо этого используйте глобальную внешнюю переменную environ в Linux®, _environ или _wenviron в Windows® или их эквиваленте. Когда вы изменяете среду, эти переменные обновляются.

Пример - доступ к среде через указатель envp
#include <stdio.h>
#include <stdlib.h>

extern int check_arguments(int argc, char **argv, char **envp);
extern void use_envp(char **envp);

/* envp is from main function */
int func(char **envp) 
{
    /* Call to setenv may cause environment
     *memory to be reallocated 
     */
    if (setenv(("MY_NEW_VAR"),("new_value"),1) != 0) 
    {
        /* Handle error */
        return -1;
    }
    /* envp not updated after call to setenv, and may
     *point to incorrect location.
     **/
    if (envp != ((void *)0)) { 
        use_envp(envp);
/* No defect on second access to
*envp because defect already raised */
    }
    return 0;
}

void  main(int argc, char **argv, char **envp)
{
    if (check_arguments(argc, argv, envp))
    {
        (void)func(envp);
    }
}

В этом примере, envp получен доступ в func() после вызова setenv это может перераспределить память среды. envp может указать на неправильное местоположение, потому что оно не обновляется после setenv изменяет среду. Никакой дефект не повышен когда use_envp() называется, потому что дефект уже повышен на предыдущей строке кода.

Коррекция — использует глобальную внешнюю переменную environ

Одна возможная коррекция должна получить доступ к среде при помощи переменной, которая всегда обновляется после вызова setenv. Например, в следующем коде, указатель envp все еще доступно от main(), но к среде получают доступ в func() через глобальную внешнюю переменную environ.

#include <stdio.h>
#include <stdlib.h>
extern char **environ;

extern int check_arguments(int argc, char **argv, char **envp);
extern void use_envp(char **envp);

int func(void)
{
    if (setenv(("MY_NEW_VAR"), ("new_value"),1) != 0) {
        /* Handle error */
        return -1;
    }
  /* Use global external variable environ
   *which is always updated after a call to setenv */
    
    if (environ != NULL) { 
        use_envp(environ);
    }
    return 0;
}

void  main(int argc, char **argv, char **envp)
{
    if (check_arguments(argc, argv, envp))
    {
        (void)func();
    }
} 

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

Группа: правило 10. Среда (ENV)
Введенный в 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". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ОПИСАЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.

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