NUM.OVERFLOW.DF

可能的数值溢出或环绕

NUM.OVERFLOW.DF 检查器会检测算术运算中可能出现的数值溢出或环绕情况。

漏洞与风险

数值溢出情况可能导致未定义的行为。此外,溢出会损害程序的可靠性和安全性。

漏洞代码示例 1

复制
  #include <stdio.h>
  void f()
  {
      unsigned short unA, unB;
      unsigned short unRet = 0;
  
      unA = 40000;
      unB = 30000;
      unRet = unA + unB;
  }

在以上示例中,Klocwork 报告第 9 行出现 NUM.OVERFLOW.DF 缺陷,因为在使用 16 位 unsigned short 的平台上,算术运算(加法)的结果超出了 unsigned short 的范围。

修正代码示例 1

复制
  typedef unsigned long long uint64_t;
  typedef unsigned int uint32_t;
  uint64_t foo(uint32_t x, uint32_t y) {
    uint64_t z;
    z = (uint64_t) ( x ) * y;
    z = (uint64_t) ( y ) * 1000000U; //or: y*1000000ULL
    return z;
  }

合规解决方案将在执行算术运算之前检查加法运算是否会超出范围,借此确保加法运算永远不会溢出。

漏洞代码示例 2

复制
 #include <stdio.h>
 void g()
 {
     signed int lX, lY;
     unsigned long long llZ = 0;
     lX = 2000000000;
     lY = 2000000000;
     llZ = (unsigned long long)(lX * lY);
 }

在此示例中,Klocwork 报告第 8 行出现 NUM.OVERFLOW.DF 缺陷,因为在使用 32 位或以下 signed int 的平台上,乘法运算会先在 32 位 (signed int) 中执行,然后才转换为 unsigned long long,这会导致溢出。

修正代码示例 2

复制
 #include <stdio.h>
 void g()
 {
     signed int lX, lY;
     unsigned long long llZ = 0;
     lX = 2000000000;
     lY = 2000000000;
     llZ = (unsigned long long) (lX) * lY;
 }

在以上符合要求的示例中,变量 lX 首先进行向上转换,这使得 lY 自动提升,最终对 unsigned long long(64 位)执行乘法运算,从而避免了溢出的发生。

相关检查器

安全培训

应用程序安全培训材料由 Secure Code Warrior 提供。

扩展

此检查器无法进行扩展。