exponenta event banner

CERT C: Rec. MEM01-C

Хранить новое значение в указателях сразу после освобождения ()

Описание

Определение правила

Хранить новое значение в указателях сразу после освобождения (). [ 1]

Внедрение Polyspace

Эта проверка проверяет отсутствие сброса освобожденного указателя.

Примеры

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

Проблема

При отсутствии сброса освобожденного указателя обнаруживаются указатели, которые были освобождены и не переназначены другим значением. После освобождения указателя данные памяти по-прежнему доступны. Чтобы очистить эти данные, необходимо также установить для указателя значение 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);
    }
}

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

Группа: Rec. 08. Управление памятью (MEM)
Представлен в R2019a

[1] Данное программное обеспечение было создано компанией MathWorks и включает в себя следующие компоненты: «Веб-сайт SEI CERT-C», © 2017 Университет Карнеги-Меллон, веб-сайт SEI CERT-C + + © 2017 Университет Карнеги-Меллон, "Стандарт кодирования SEI CERT C - Правила разработки безопасных, Надежные и безопасные системы - 2016 Edition ", © 2016 Университет Карнеги-Меллон, и "Стандарт кодирования SEI CERT C++ - Правила разработки безопасных, Надежные и безопасные системы в C++ - 2016 Edition "© 2016 Университет Карнеги-Меллон, со специальным разрешением от его Института программного обеспечения.

ЛЮБОЙ МАТЕРИАЛ УНИВЕРСИТЕТА КАРНЕГИ МЕЛЛОНА И/ИЛИ ЕГО ПРОГРАММНОГО ИНЖЕНЕРНОГО ИНСТИТУТА, СОДЕРЖАЩИЙСЯ В НАСТОЯЩЕМ ДОКУМЕНТЕ, ПОСТАВЛЯЕТСЯ КАК ЕСТЬ. УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ, ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, В ОТНОШЕНИИ ЛЮБЫХ ВОПРОСОВ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ГАРАНТИИ ПРИГОДНОСТИ ДЛЯ ЦЕЛЕЙ ИЛИ ТОВАРНОЙ ПРИГОДНОСТИ, ИСКЛЮЧИТЕЛЬНОСТИ ИЛИ РЕЗУЛЬТАТОВ, ПОЛУЧЕННЫХ ОТ ИСПОЛЬЗОВАНИЯ УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ В ОТНОШЕНИИ СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКИХ ПРАВ.

Данное программное обеспечение и связанная с ним документация не были рассмотрены и не одобрены Университетом Карнеги-Меллона или его Институтом разработки программного обеспечения.