Bitwise operation on negative value

Неопределенное поведение для побитовых операций с отрицательными значениями

Описание

Этот дефект возникает, когда побитовые операторы (>>, ^, |, ~, 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);
}

Информация о результатах

Группа: Численный
Язык: C | C++
По умолчанию: Off
Синтаксис командной строки: BITWISE_NEG
Влияние: Средний
ИДЕНТИФИКАТОР CWE: 682, 758
Введенный в R2016b