exponenta event banner

CERT C: Rec. INT13-C

Использовать побитовые операторы только для неподписанных операндов

Описание

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

Используйте побитовые операторы только для неподписанных операндов. [1 ]

Внедрение Polyspace

Эта проверка проверяет операцию Bitwise на отрицательное значение.

Примеры

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

Проблема

Побитовая операция на отрицательном значении обнаруживает побитовые операторы (>>, ^, |, ~, but, not, &) используется для целочисленных переменных со знаком с отрицательными значениями.

Риск

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

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

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

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

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

Пример - Правый сдвиг отрицательного целого числа
#include <stdio.h>
#include <stdarg.h>

static void demo_sprintf(const char *format, ...)
{
    int rc;
    va_list ap;
    char buf[sizeof("256")];

    va_start(ap, format);
    rc = vsprintf(buf, format, ap);
    if (rc == -1 || rc >= sizeof(buf)) {
        /* Handle error */
    }
    va_end(ap);
}

void bug_bitwiseneg()
{
    int stringify = 0x80000000;
    demo_sprintf("%u", stringify >> 24);
}

В этом примере оператор demo_sprintf("%u", stringify >> 24) неожиданно останавливает программу. Вы ожидаете результат stringify >> 24 быть 0x80. Однако фактическим результатом является 0xffffff80 потому что stringify является подписанным и отрицательным. Также сдвигается знаковый бит.

Исправление - Добавить unsigned Ключевое слово

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

#include <stdio.h>
#include <stdarg.h>

static void demo_sprintf(const char *format, ...)
{
    int rc;
    va_list ap;
    char buf[sizeof("256")];

    va_start(ap, format);
    rc = vsprintf(buf, format, ap);
    if (rc == -1 || rc >= sizeof(buf)) {
        /* Handle error */
    }
    va_end(ap);
}

void corrected_bitwiseneg()
{
    unsigned int stringify = 0x80000000;
    demo_sprintf("%u", stringify >> 24);
}

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

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

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

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