exponenta event banner

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

Убедитесь, что операции со подписанными целыми числами не приводят к переполнению

Описание

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

Убедитесь, что операции со подписанными целыми числами не приводят к переполнению. [1 ]

Внедрение Polyspace

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

  • Переполнение целого числа.

  • Операнд запятнанной дивизии.

  • Запятнанный по модулю операнд.

Примеры

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

Проблема

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

Точное распределение ресурсов хранения для различных типов с плавающей запятой зависит от процессора. Посмотрите Target processor type (-target). W

Риск

Переполнение целочисленных чисел со знаком приводит к неопределенному поведению.

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

Исправление зависит от первопричины дефекта. Часто детали результата показывают последовательность событий, которые привели к дефекту. Этот список событий используется для определения того, как переменные в вычислениях переполнения получают свои текущие значения. Исправление может быть реализовано для любого события в последовательности. Если сведения о результатах не отображают историю событий, можно выполнить обратную трассировку, щелкнув правой кнопкой мыши параметры в исходном коде и просмотреть предыдущие связанные события. См. также раздел Интерпретация результатов поиска ошибок в интерфейсе пользователя Polyspace Desktop.

Устранить дефект можно путем:

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

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

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

  • Храните целочисленные значения переменных в пределах половины диапазона целых чисел со знаком.

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

См. примеры исправлений ниже.

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

Пример - Добавление максимального целого числа
#include <limits.h>

int plusplus(void) {

    int var = INT_MAX;
    var++;             
    return var;
}

В третьем операторе этой функции переменная var увеличивают на единицу. Но ценность var является максимальным целым значением, поэтому int не может представлять единицу плюс максимальное целое значение.

Корректировка - другой тип склада

Одной из возможных корректировок является изменение типов данных. Сохранить результат операции в большем типе данных (Обратите внимание, что на 32-разрядном компьютере, int и long имеет одинаковый размер). В этом примере, на 32-разрядной машине, возвращая long long вместо int, ошибка переполнения исправлена.

#include <limits.h>

long long plusplus(void) {

    long long lvar = INT_MAX;
    lvar++;
    return lvar;
}
Проблема

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

Риск

  • Если числитель является минимально возможным значением, а знаменатель - -1, операция разделения переполняется, поскольку результат не может быть представлен текущим размером переменной.

  • Если знаменатель равен нулю, операция деления может привести к аварийному завершению программы.

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

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

Перед выполнением деления проверьте значения операндов. Проверка знаменателей 0 или -1и числители минимального целого значения.

Пример - Деление аргументов функции
#include <limits.h>
#include <stdio.h>

extern void print_int(int);

int taintedintdivision(void) {
    long num, denum;
    scanf("%lf %lf", &num, &denum);
    int r =  num/denum; 
    print_int(r);
    return r;
}

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

Коррекция - проверка значений

Одной из возможных корректировок является проверка значений числителя и знаменателя перед выполнением деления.

#include <limits.h>
#include <stdio.h>

extern void print_long(long);

int taintedintdivision(void) {
    long num, denum;
    scanf("%lf %lf", &num, &denum);
    long res= 0;
    if (denum!=0 && !(num==INT_MIN && denum==-1)) {
        res = num/denum;
    }
    print_long(res);
    return res;
}
Проблема

Запятнанный по модулю операнд проверяет операнды остатка % операции. Bug Finder помечает операции по модулю с одним или несколькими запятнанными операндами.

Риск

  • Если второй операнд остатка равен нулю, операция остатка завершается неуспешно, что приводит к аварийному завершению программы.

  • Если второй операнд остатка -1, операция остатка может переполняться, если операция остатка реализуется на основе операции разделения, которая может переполняться.

  • Если один из операндов отрицательный, результат операции является неопределенным. Для C89 операция по модулю не стандартизирована, поэтому результат отрицательных операндов определяется реализацией.

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

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

Перед выполнением операции по модулю проверьте значения операндов. Проверьте второй операнд на значения 0 и -1. Проверьте оба операнда на наличие отрицательных значений.

Пример - Modulo с незащищенным входом
#include<stdio.h>
extern void print_int(int);

int taintedintmod(void) {
	int userden;
	scanf("%d",&userden);
    int rem =  128%userden; 
    print_int(rem);
    return rem;
}

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

Коррекция - проверка значений операндов

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

#include<stdio.h>
extern void print_int(int);

int taintedintmod(void) {
	int userden;
	scanf("%d",&userden);
	int rem = 0;
    if (userden > 0) { 
        rem = 128 % userden; 
    }
    print_int(rem);
    return rem;
}

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

Группа: Правило 04. Целые числа (INT)
Представлен в R2019a

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

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

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