Environment pointer invalidated by previous operation

Вызовите к setenv или putenv функция семейства изменяет среду, на которую указывает указатель

Описание

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

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

Риск

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

Фиксация

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

Примеры

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

#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();
    }
} 

Информация о результате

Группа: Программирование
Язык: C | C++
Значение по умолчанию: На для рукописного кода, прочь для сгенерированного кода
Синтаксис командной строки: INVALID_ENV_POINTER
Удар: Средняя
ID CWE: 825
Введенный в R2018a