exponenta event banner

CERT C: ARR32-C правил

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

Описание

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

Убедитесь, что аргументы размера для массивов переменной длины находятся в допустимом диапазоне. [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

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

#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 Университет Карнеги-Меллон, со специальным разрешением от его Института программного обеспечения.

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

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