ISO/IEC TS 17961 [addrescape]

Выход адреса автоматического объекта

Описание

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

Выход адреса автоматического object.[1]

Реализация Polyspace

Это средство проверки проверяет на эти проблемы:

  • Указатель или ссылка, чтобы сложить переменный осциллограф отъезда.

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

Примеры

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

Проблема

Указатель или ссылка, чтобы сложить переменный осциллограф отъезда происходят, когда указатель или ссылка на локальную переменную оставляют осциллограф переменной. Например:

  • Функция возвращает указатель на локальную переменную.

  • Функция выполняет присвоение globPtr = &locVar. globPtr глобальная переменная указателя и locVar локальная переменная.

  • Функция выполняет присвоение *paramPtr = &locVar. paramPtr параметр функции то есть, например, int** указатель и locVar локальный int переменная.

  • Метод C++ выполняет присвоение memPtr = &locVar. memPtr элемент данных указателя класса, которому принадлежит метод. locVar переменная локальная переменная к методу.

Дефект также применяется к выделенному использованию памяти alloca функция. Дефект не применяется к статическим, локальным переменным.

Риск

Локальные переменные выделяются адрес на стеке. Если осциллограф локальной переменной заканчивается, этот адрес доступен для повторного использования. Используя этот адрес, чтобы получить доступ к значению локальной переменной вне переменной scope может вызвать неожиданное поведение.

Если указатель на локальную переменную оставляет осциллограф переменной, Polyspace® Bug Finder™ подсвечивает дефект. Дефект появляется, даже если вы не используете адрес, сохраненный в указателе. Для удобного в сопровождении кода это - хорошая практика, чтобы не позволить указателю оставлять переменную scope. Даже если вы не используете адрес в указателе теперь, кто-то еще использующий вашу функцию может использовать адрес, вызывая неопределенное поведение.

Фиксация

Не позволяйте указателю или ссылке на локальную переменную оставлять переменную scope.

Пример - указатель на локальную переменную, возвращенную в функцию
void func2(int *ptr) {
    *ptr = 0;
}

int* func1(void) {
    int ret = 0;
    return &ret ;
}
void main(void) {
    int* ptr = func1() ;
    func2(ptr) ;
}

В этом примере, func1 возвращает указатель на локальную переменную ret.

В main, ptr точки к адресу локальной переменной. Когда ptr получен доступ в func2, доступ недопустим потому что осциллограф ret ограничивается func1,

Проблема

Использование автоматической переменной как 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 */
    }
}

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

Разрешимость: неразрешимый
Введенный в R2019a

[1]  Выписки из стандарта "Техническая характеристика ISO/IEC TS 17961 - 2013-11-15" воспроизводятся с соглашением о AFNOR. Только исходный и полный текст стандарта, как опубликовано Выпусками AFNOR - доступный через веб-сайт www.boutique.afnor.org - имеет нормативное значение.