Missing reset of a freed pointer

Указатель на free не сопровождается оператором сброса для удаления оставшихся данных

Описание

Этот дефект возникает, когда указатель освобождается и не переопределяется другое значение. После освобождения указателя данные памяти все еще доступны. Чтобы удалить эти данные, указатель должен быть также установлен в 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++
По умолчанию: Off
Синтаксис командной строки: MISSING_FREED_PTR_RESET
Влияние: Низкое
ИДЕНТИФИКАТОР CWE: 415, 416, 825
Введенный в R2016b