CERT C++: STR53-CPP

Доступ к элементу проверки диапазона

Описание

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

Элемент проверки диапазона access.[1]

Реализация Polyspace

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

  • Доступ к массиву за пределы.

  • Доступ к массиву с испорченным индексом.

  • Указатель разыменовывает с испорченным смещением.

Примеры

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

Проблема

Доступ к массиву за пределы происходит, когда индекс массива выходит за пределы области значений [0...array_size-1] во время доступа к массиву.

Риск

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

Фиксация

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

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

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

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

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

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

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

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

Пример - доступ к массиву за пределы ошибка
#include <stdio.h>

void fibonacci(void)
{
    int i;
    int fib[10];
 
    for (i = 0; i < 10; i++) 
       {
        if (i < 2) 
            fib[i] = 1;
         else 
            fib[i] = fib[i-1] + fib[i-2];
       }

    printf("The 10-th Fibonacci number is %i .\n", fib[i]);   
    /* Defect: Value of i is greater than allowed value of 9 */
}

Массив fib присвоен размер 10. Индекс массива для fib позволил значения [0,1,2,...,9]. Переменная i имеет значение 10, когда оно выходит из for- цикл. Поэтому printf оператор пытается получить доступ к fib[10] через i.

Коррекция — сохраняет индекс массива в границах массивов

Одна возможная коррекция должна распечатать fib[i-1] вместо fib[i] после for- цикл.

#include <stdio.h>

void fibonacci(void)
{
   int i;
   int fib[10];

   for (i = 0; i < 10; i++) 
    {
        if (i < 2) 
            fib[i] = 1;
        else 
            fib[i] = fib[i-1] + fib[i-2];
    }

    /* Fix: Print fib[9] instead of fib[10] */
    printf("The 10-th Fibonacci number is %i .\n", fib[i-1]); 
}

printf доступы к оператору fib[9] вместо fib[10].

Проблема

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

Риск

Индекс может найтись вне допустимой области значений массивов. Если испорченный индекс находится вне области значений массивов, он может вызвать:

  • Недостаточное наполнение буфера / подписывает — пишущий в память перед началом буфера.

  • Переполнение буфера — пишущий в память после конца буфера.

  • Зачитываясь буфер — доступ к памяти после конца целенаправленного буфера.

  • Под чтением буфер или память доступа перед началом целенаправленного буфера.

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

Фиксация

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

Пример - индекс использования, чтобы возвратить буферность
#include <stdlib.h>
#include <stdio.h>
#define SIZE100 100
extern int tab[SIZE100];
static int tainted_int_source(void) {
  return strtol(getenv("INDEX"),NULL,10);
}
int taintedarrayindex(void) {
	int num = tainted_int_source();
    return tab[num];  
}

В этом примере, индекс num получает доступ к массиву tab. Индекс num получен из небезопасного источника и функционального taintedarrayindex не проверяет, чтобы видеть если num в области значений tab.

Коррекция — область значений проверки перед использованием

Одна возможная коррекция должна проверять тот num находится в области значений перед использованием его.

#include <stdlib.h>
#include <stdio.h>
#define SIZE100 100
extern int tab[SIZE100];
static int tainted_int_source(void) {
	return strtol(getenv("INDEX"),NULL,10);
}
int taintedarrayindex(void) {
	int num = tainted_int_source();
	if (num >= 0 && num < SIZE100) {
		return tab[num]; 
	} else {
		return -1;
	}
}

Проблема

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

Эта проверка фокусируется на динамически выделенных буферах. Для статических буферных смещений смотрите Array access with tainted index.

Риск

Индекс может найтись вне допустимой области значений массивов. Если испорченный индекс находится вне области значений массивов, он может вызвать:

  • Недостаточное наполнение буфера / подписывает, или пишущий в память перед началом буфера.

  • Переполнение буфера, или пишущий в память после конца буфера.

  • По чтению буфера или доступу к памяти после конца целенаправленного буфера.

  • Под чтением буфер или память доступа перед началом целенаправленного буфера.

Атакующий может использовать недопустимое чтение или записать, чтобы поставить под угрозу вашу программу.

Фиксация

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

Пример - разыменовывает массив указателей
#include <stdio.h>
#include <stdlib.h>
enum {
    SIZE10  =  10,
    SIZE100 = 100,
    SIZE128 = 128
};
extern void read_pint(int*);

int taintedptroffset(void) {
    int offset;
    scanf("%d",&offset);
    int* pint = (int*)calloc(SIZE10, sizeof(int));
    int c = 0;
    if(pint) {
        /* Filling array */
        read_pint(pint);
        c = pint[offset];
        free(pint);
    }
    return c;
}

В этом примере функция инициализирует целочисленный указатель pint. Указатель разыменовывается с помощью входного индекса offset. Значение offset мог найтись вне области значений указателя, вызвав ошибку из области значений.

Коррекция — индекс проверки прежде разыменовывает

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

#include <stdlib.h>
#include <stdio.h>
enum {
    SIZE10  =  10,
    SIZE100 = 100,
    SIZE128 = 128
};
extern void read_pint(int*);

int taintedptroffset(void) {
    int offset;
    scanf("%d",&offset);
    int* pint = (int*)calloc(SIZE10, sizeof(int));
    int c = 0;
    if (pint) {
        /* Filling array */
        read_pint(pint);
        if (offset>0 && offset<SIZE10) {
            c = pint[offset];
        }
        free(pint);
    }
    return c;
}

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

Группа: 05. Символы и строки (STR)
Введенный в 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". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ОПИСАЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.

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