CERT C: Rule INT31-C

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

Описание

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

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

Реализация Polyspace

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

  • Целочисленное переполнение преобразования.

  • Вызовите к memset с непреднамеренным значением.

  • Подпишите целочисленное переполнение преобразования изменения.

  • Испорченное преобразование изменения знака.

  • Переполнение преобразования беззнаковых целых чисел.

Примеры

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

Проблема

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

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

Риск

Целочисленное преобразование переполняет результата в неопределенном поведении.

Фиксация

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

Можно зафиксировать дефект:

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

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

В общем случае избегайте преобразований в меньшие целочисленные типы.

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

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

Пример - преобразующий от int к char

char convert(void) {

    int num = 1000000;

    return (char)num;
}

В операторе возврата, целочисленная переменная num преобразован в char. Однако 8-битный или 16-битный символ не может представлять 1000000, потому что требуется по крайней мере 20 битов. Так переполнение операции преобразования.

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

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

long convert(void) {

    int num = 1000000;

    return (long)num;
}

Проблема

Вызов memset с непреднамеренным значением происходит, когда Polyspace® Bug Finder™ обнаруживает использование memset или wmemset функция с возможно неправильными аргументами.

void *memset (void *ptr, int value, size_t num) заполняет первый num байты блока памяти, что ptr точки к с заданным value. Если аргумент value является неправильным, блок памяти инициализируется непреднамеренным значением.

Непреднамеренная инициализация может произойти в следующих случаях.

ПроблемаРискВозможная фиксация
Вторым аргументом является '0' вместо 0 или '\0'.Значение ASCII символьного '0' 48 (десятичное число), 0x30 (шестнадцатеричный), 069 (восьмеричный), но не 0 (или '\0') .Если вы хотите инициализировать '0', используйте одно из значений ASCII. В противном случае используйте 0 или '\0'.
Вторые и третьи аргументы, вероятно, инвертируются. Например, третий аргумент является литералом, и второй аргумент не является литералом.Если порядок инвертируется, блок памяти непреднамеренного размера инициализируется неправильными аргументами.Инвертируйте порядок аргументов.
Второй аргумент не может быть представлен в байте.Если второй аргумент не может быть представлен в байте, и вы ожидаете, что каждый байт блока памяти будет заполнен тем аргументом, инициализация не происходит, как предназначено.

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

Например, замените memset(a, -13, sizeof(a)) с memset(a, (-13) & 0xFF, sizeof(a)).

Фиксация

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

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

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

Пример - значение не может быть представлено в байте

#include <string.h>

#define SIZE 32
void func(void) {
    char buf[SIZE];
    int c = -2;
    memset(buf, (char)c, sizeof(buf));
}

В этом примере, (char)c не может быть представлен в байте.

Коррекция — применяет бросок

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

#include <string.h>

#define SIZE 32
void func(void) {
    char buf[SIZE   ];
    int c = -2;
    memset(buf, (unsigned char)c, sizeof(buf)); 
}

Проблема

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

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

Фиксация

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

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

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

Пример - преобразует от unsigned char к char

char sign_change(void) {
    unsigned char count = 255;

    return (char)count;
}

В операторе возврата, символьной переменной count без знака преобразован в символ со знаком. Однако char имеет 8 битов, 1 для знака константы и 7, чтобы представлять номер. Операция преобразования переполняется потому что 255 использования 8 битов.

Коррекция — типы преобразования Изменения

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

int sign_change(void) {
    unsigned char count = 255;

    return (int)count;
}

Проблема

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

Например, функции то использование size_t когда аргументы неявно преобразуют аргумент в беззнаковое целое. Некоторые функции, которые неявно преобразуют size_t :

bcmp
memcpy
memmove
strncmp
strncpy
calloc
malloc
memalign

Риск

Если вы преобразуете маленькое отрицательное число в без знака, результатом является большое положительное число. Большое положительное число может создать уязвимости системы обеспечения безопасности. Например, если вы используете значение без знака в:

  • Стандартные программы емкости памяти — причины, выделяющие проблемы памяти.

  • Стандартные программы обработки строк — вызывают переполнение буфера.

  • Контуры цикла — вызывают бесконечные циклы.

Фиксация

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

Пример - значение памяти аппарата с аргументом размера

#include <stdlib.h>
#include <string.h>

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

void bug_taintedsignchange(int size) {
    char str[SIZE128] = "";
    if (size<SIZE128) {
        memset(str, 'c', size); 
    }
}

В этом примере, char буфер создается и заполнил использование memset. Аргумент размера к memset входной параметр к функции.

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

Коррекция — контрольное число size

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

#include <stdlib.h>
#include <string.h>

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

void corrected_taintedsignchange(int size) {
    char str[SIZE128] = "";
    if (size>0 && size<SIZE128) {
        memset(str, 'c', size);  
    }
}

Проблема

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

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

Риск

Целочисленное преобразование переполняет результата в неопределенном поведении.

Фиксация

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

Можно зафиксировать дефект:

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

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

В общем случае избегайте преобразований в меньшие целочисленные типы.

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

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

Пример - преобразующий от int к char

unsigned char convert(void) {
    unsigned int unum = 1000000U;

    return (unsigned char)unum;  
}

В операторе возврата, переменной unum беззнаковых целых чисел преобразован в тип символов без знака. Однако преобразование переполняется, потому что 1000000 требует по крайней мере 20 битов. Стандарт языка программирования C не просматривает переполнение без знака как ошибку, потому что программа автоматически уменьшает результат модулем максимальное значение плюс 1. В этом примере, unum уменьшается 2^8 по модулю потому что символьный тип данных может только представлять 2^8-1.

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

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

unsigned long convert(void) {
    unsigned int unum = 1000000U;

    return (unsigned long)unum;  
}

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

Группа: правило 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". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ВЫРАЗИЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.

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