主要内容

本页采用了机器翻译。点击此处可查看最新英文版本。

CERT C:Rec.INT13-C

Use bitwise operators only on unsigned operands

描述

规则定义

Use bitwise operators only on unsigned operands.1

Polyspace 实现

规则检查项检查是否存在对负值进行按位运算

扩展检查项

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

示例

全部展开

问题

负值上的位运算检测对负值有符号整数变量使用的位运算符(>>^|~butnot&)。

风险

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

  • 对负值的位运算因编译器而异。

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

修复

执行按位运算时,请使用 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); //Noncompliant
}

在此示例中,语句 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 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.