SV.FMT_STR.SCAN_FORMAT_MISMATCH.BAD

规范和参数不匹配

扫描函数参数可以用作各类项目的指针,因此这些项目占用的内存量会有所不同。如果扫描函数参数指向的内存项目小于对应的格式字符串规范所预期的大小,则可能产生漏洞。如果代码中扫描参数指向的内存项目的类型大小与对应的格式字符串规范不匹配,则 SV.FMT_STR.SCAN_FORMAT_MISMATCH.BAD 检查器会标记出相关代码。

漏洞与风险

不匹配的参数和格式字符串规范会造成内存访问冲突,从而可能导致意外的程序执行结果。有可能会出现未定义的行为和异常的程序终止。

漏洞代码示例

复制
   # include <string>
   # include <stdio.h>

   std::string scan_int() {
     int length;
     std::string str;
     scanf("%lf", &length); // defect
     scanf("%s\n", str);    // defect
   }

Klocwork 标记了第 7 行,因为 %lf 规范与 int 类型的参数不匹配。double 类型(%lf 规范所预期的类型)通常所需的内存量总是大于 int 类型(实际提供的指针所指向的类型)所需的内存量。当实际上分配的是 int 类型所需的内存量,而又尝试访问 double 类型所需的内存量时,则可能发生内存访问冲突。

标记了第 8 行,因为预期为 %s 规范提供 C 字符串,而实际上提供的却是对象。当尝试将字节写入由对象占用的内存时,则可能导致内存访问冲突。

修正代码示例

复制
   # include <string>
   # include <stdio.h>

   std::string scan_int() {
     int length;
     char *str;
     scanf("%d", &length); 
     str = (char *)malloc(length + 1);
     scanf("%s\n", str);   
  }

在经修正的代码的第 7 行中,使用正确的格式说明符 %d 打印整数值。第 9 行中使用的是初始分配的 C 字符串,而不是 std::string。