CERT C: Rec. INT04-C

Осуществите пределы на целочисленных значениях, происходящих из испорченных источников

Описание

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

Осуществите пределы на целочисленных значениях, происходящих из испорченных источников. [1]

Примеры

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

Описание

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

Риск

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

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

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

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

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

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

Фиксация

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

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

#define SIZE100 100
extern int tab[SIZE100];

int taintedarrayindex(int num) {
    return tab[num];  
}

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

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

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

#define SIZE100 100
extern int tab[SIZE100];

int taintedarrayindex(int num) {
    if (num >= 0 && num < SIZE100) {
           return tab[num]; 
    } else {
        return -9999;
    }
}

Описание

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

Риск

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

Фиксация

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

Пример - контур цикла от входного параметра

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

int taintedloopboundary(int count) {
    int res = 0;
    for (int i=0 ; i < count; ++i) {
        res += i;
    }
    return res;
}

В этом примере функция использует входной параметр, чтобы циклично выполнить count \times. count мог быть любой номер, потому что значение не проверяется прежде, чем запустить цикл for.

Коррекция — управление циклом проверки

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

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

int taintedloopboundary(int count) {
    int res = 0;

    if (count>0 && count<SIZE128) {
        for (int i=0 ; i<count ; ++i) { 
            res += i;
        }
    }
    return res;
}

Описание

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

Риск

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

Фиксация

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

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

#include "stdlib.h"

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

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

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

Одна возможная коррекция должна проверять размер памяти, которую вы хотите выделить прежде, чем выполнить 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;
}

Описание

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

Риск

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

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

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

Фиксация

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

Пример - входной параметр, используемый в качестве размера VLA

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

int taintedvlasize(int size) {

    int tabvla[size];
    int res = 0;
    for (int i=0 ; i<SIZE10 ; ++i) {
        tabvla[i] = i*i;
        res += tabvla[i];
    }
    return res;
}

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

Коррекция — проверяет размер VLA

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

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

int taintedvlasize(int size) {
    int res = 0;
    if (size>SIZE10 && size<SIZE100) {
        int tabvla[size]; 
        for (int i=0 ; i<SIZE10 ; ++i) {
            tabvla[i] = i*i;
            res += tabvla[i];
        }
    }
    return res;
}

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

Группа: Rec. 04. Целые числа (INT)

Введенный в 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". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ВЫРАЗИЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.

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