CERT C: правило MEM35-C

Выделите достаточную память для объекта

Описание

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

Выделите достаточную память для объекта. [1]

Примеры

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

Описание

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

Когда указатель присвоен адрес, блок памяти сопоставлен с указателем. Вы не можете получить доступ к памяти, кроме того блокируют использование указателя.

Риск

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

Фиксация

Фиксация зависит от первопричины дефекта. Например, вы разыменовали указатель в цикле, и одна из этих ситуаций произошла:

  • Верхняя граница цикла является слишком большой.

  • Вы использовали адресную арифметику с указателями, чтобы усовершенствовать указатель с неправильным значением для шага указателя.

Чтобы устранить проблему, необходимо изменить связанный цикл или значение шага указателя.

Часто детали результата показывают последовательность событий, которые привели к дефекту. Можно реализовать закрепление на любом событии в последовательности. Если детали результата не показывают историю события, можно проследить использование, щелкните правой кнопкой по опциям по исходному коду и смотрите предыдущие связанные события. См. также Интерпретируют Результаты Polyspace Bug Finder.

Смотрите примеры мер ниже.

Если вы не хотите устранять проблему, добавьте комментарии в свой результат или код, чтобы избежать другого анализа. Смотрите Результаты Polyspace Адреса Через Исправления ошибок или Комментарии.

Пример - доступ к Указателю за пределы ошибка

int* Initialize(void)
{
 int arr[10];
 int *ptr=arr;

 for (int i=0; i<=9;i++)
   {
    ptr++;
    *ptr=i;
    /* Defect: ptr out of bounds for i=9 */
   }

 return(arr);
}

ptr присвоен адрес arr, который указывает на блок памяти размера 10*sizeof(int). В for - цикл, ptr постепенно увеличивается 10 раз. В последней итерации цикла ptr указывает вне блока памяти, присвоенного ему. Поэтому это не может быть разыменовано.

Исправление — указатель проверки остается в границах

Одно возможное исправление должно инвертировать порядок шага и разыменовать ptr.

int* Initialize(void)
{
 int arr[10];
 int *ptr=arr;

 for (int i=0; i<=9;i++)
     {
      /* Fix: Dereference pointer before increment */
      *ptr=i;
      ptr++;
     }

 return(arr);
}

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

Описание

Выделение памяти с испорченным размером проверяет функции выделения памяти, такие как calloc или malloc, для аргументов размера из необеспеченных источников.

Риск

Неконтролируемое выделение памяти может заставить вашу программу запрашивать слишком много системной памяти. Это последствие может привести к катастрофическому отказу из-за условия из памяти, или присваивающий слишком много ресурсов.

Фиксация

Прежде, чем выделить память, проверяйте значение своих аргументов, чтобы проверять, что они не превышают границы.

Пример - выделяет память Используя входной параметр

#include "stdlib.h"

int* bug_taintedmemoryallocsize(size_t size) {
    int* p = (int*)malloc(size);
    return p;
}

В этом примере malloc выделяет объем памяти size для указателя p. size является внешней переменной, так могло быть любое значение размера. Если размер больше, чем объем памяти, вы имеете в наличии, ваша программа могла бы отказать.

Исправление — Размер Проверки Памяти, которая будет Выделена

Одно возможное исправление должно проверять размер памяти, которую вы хотите выделить прежде, чем выполнить операцию malloc. Эти проверки в качестве примера, чтобы видеть, положителен ли размер и меньше, чем максимальный размер.

#include "stdlib.h"

enum {
    SIZE10  =  10,
    SIZE100 = 100,
    SIZE128 = 128
};

int* corrected_taintedmemoryallocsize(int size) {
    int* p = NULL;
    if (size>0 && size<SIZE128) {          /* Fix: Check entry range before use */
        p = (int*)malloc((unsigned int)size);
    }
    return p;
}

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

Группа: правило 08. Управление памятью (MEM)

Введенный в R2019a


[1]  Это программное обеспечение было создано MathWorks, включающим фрагменты: “Веб-сайт SEI CERT-C”, © 2017 Carnegie Mellon University, веб-сайт SEI CERT-C © 2017 Carnegie Mellon University”, CERT SEI C Кодирование Стандарта – Правил для Разработки безопасных, Надежных и Защищенных систем – 2 016 Выпусков”, © 2016 Carnegie Mellon University, and “CERT SEI Стандарт Кодирования C++ – Правил для Разработки безопасных, Надежных и Защищенных систем на C++ – 2 016 Выпусков” © 2016 Carnegie Mellon University, со специальным разрешением от его Института программной инженерии.

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

Это программное обеспечение и сопоставленная документация не были рассмотрены, ни являются подтвержденным Университетом Карнеги-Меллон или его Институтом программной инженерии.