CERT C: Rule ARR32-C

Убедитесь, что аргументы в size для массивов переменной длины находятся в допустимой области значений

Описание

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

Убедитесь, что аргументы в пользу размера для массивов переменной длины находятся в допустимой области значений.[1]

Реализация Polyspace

Эта проверка проверяет на наличие следующих проблем:

  • Выделение памяти с испорченным размером.

  • Испорченный размер массива переменной длины.

Примеры

расширить все

Проблема

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

Риск

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

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

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

Пример - Выделение памяти с помощью входного параметра
#include<stdio.h>
#include <stdlib.h>

int* bug_taintedmemoryallocsize(void) {
    size_t size;
    scanf("%zu", &size);
    int* p = (int*)malloc(size);
    return p;
}

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

Коррекция - Проверяйте размер выделяемой памяти

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

#include<stdio.h>
#include <stdlib.h>

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

int* corrected_taintedmemoryallocsize(void) {
    size_t size;
    scanf("%zu", &size);
    int* p = NULL;
    if (size>0 && size<SIZE128) {          /* Fix: Check entry range before use */
        p = (int*)malloc((unsigned int)size);
    }
    return p;
}
Проблема

Испорченный размер массива переменной длины обнаруживает массивы переменной длины (VLA), размер которых получен из небезопасного источника.

Риск

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

Если размер не положителен, поведение VLA не определено. Ваша программа работает не так, как ожидалось.

Если размер не ограничен, VLA может вызвать истощение памяти или переполнение стека.

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

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

Пример - Входной параметр, используемый как размер VLA
#include<stdio.h>
#inclule<stdlib.h>
#define LIM 40

long squaredSum(int size) {

	int tabvla[size];
	long res = 0;
	for (int i=0 ; i<LIM-1 ; ++i) {
		tabvla[i] = i*i;
		res += tabvla[i];
	}
	return res;
}
int main(){
	int size;
	scanf("%d",&size);
	//...
	long result = squaredSum(size);
	//...
	return 0;
}

В этом примере размер массива переменной длины основан на входном параметре. Поскольку этот входной параметр не проверен, размер может быть отрицательным или слишком большим.

Коррекция - Проверяйте размер VLA

Одной из возможных коррекций является проверка переменной size перед созданием массива переменной длины. Этот пример проверяет, больше ли размер 10 и меньше 100, перед созданием VLA

#include <stdio.h>
#include <stdlib.h>
#define LIM 40

long squaredSum(int size) {
	long res = 0;
	if (size>0 && size<LIM){
		int tabvla[size];
		for (int i=0 ; i<size || i<LIM-1 ; ++i) {
			tabvla[i] = i*i;
			res += tabvla[i];
		}
	}else{
		res = -1;
	}
	return res;
}
int main(){
	int size;
	scanf("%d",&size);
	//...
	long result = squaredSum(size);
	//...
	return 0;
}

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

Группа: Правило 06. Массивы (ARR)
Введенный в R2019a

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

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

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