exponenta event banner

Отсутствует сброс освобожденного указателя

Указатель free не сопровождается инструкцией reset для очистки оставшихся данных

Описание

Этот дефект возникает, когда указатель освобождается и не переназначается другим значением. После освобождения указателя данные памяти по-прежнему доступны. Чтобы очистить эти данные, необходимо также установить для указателя значение NULL или другое значение.

Риск

Отказ от сброса указателей может вызвать зависание указателей. Висячие указатели могут вызывать:

  • Освобождение уже освобожденной памяти.

  • Чтение из или запись в уже освобожденную память.

  • Хакеры выполняют код, хранящийся в свободных указателях или с уязвимыми разрешениями.

Зафиксировать

После освобождения указателя, если он не был сразу назначен другому действительному адресу, установите для указателя значение NULL.

Примеры

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

#include <stdlib.h>
enum {
    SIZE3   = 3,
    SIZE20  = 20
};

void missingfreedptrreset()
{
    static char *str = NULL;

    if (str == NULL)
        str = (char *)malloc(SIZE20);

    if (str != NULL)
        free(str);
}

В этом примере указатель str освобождается в конце программы. Следующий вызов bug_missingfreedptrrese может потерпеть неудачу, потому что str не имеет значение NULL, и инициализация в значение NULL может быть недопустимой.

Коррекция - переопределение free для освобождения и сброса

Одной из возможных корректировок является настройка free чтобы при освобождении указателя он автоматически сбрасывался.

#include <stdlib.h>
enum {
    SIZE3   = 3,
    SIZE20  = 20
};

static void sanitize_free(void **p)
{
    if ((p != NULL) && (*p != NULL))
    {
        free(*p);
        *p = NULL;
    }
}

#define free(X) sanitize_free((void **)&X)

void missingfreedptrreset()
{
    static char *str = NULL;

    if (str == NULL)
        str = (char *)malloc(SIZE20);

    if (str != ((void *)0))
    {
        free(str);
    }
}

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

Группа «Надлежащая практика»
Язык: C | C++
По умолчанию: Откл.
Синтаксис командной строки: MISSING_FREED_PTR_RESET
Воздействие: Низкий
CWE ID: 415, 416, 825
Представлен в R2016b