主要内容

对负值执行按位运算

对负值执行按位运算的未定义行为

描述

当按位运算符(>>^|~butnot&)用于具有负值的有符号整数变量时,会出现此缺陷。

风险

如果有符号整数的值为负数,则按位运算可能会出现意外结果,因为:

  • 对负值执行按位运算可以产生特定于编译器的结果。

  • 意外的计算可能会导致其他漏洞,例如缓冲区溢出。

修复

执行按位运算时,请使用 unsigned 整数以避免出现意外结果。

扩展检查项

当输入值未知并且只有一部分输入会导致问题时,默认的 Bug Finder 分析可能不会引发此缺陷。要检查由特定系统输入值引起的缺陷,请运行更严格的 Bug Finder 分析。请参阅Extend Bug Finder Checkers to Find Defects from Specific System Input Values

示例

全部展开

#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++
默认值:关闭
命令行语法:BITWISE_NEG
影响中等

版本历史记录

在 R2016b 中推出