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

Вызовите к 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