SV.FMT_STR.PRINT_FORMAT_MISMATCH.UNDESIRED

非预期的规范和参数匹配

SV.FMT_STR.PRINT_FORMAT_MISMATCH.UNDESIRED 检查器会标记那些打印函数参数与对应的格式字符串规范不匹配的代码。在这些情况中,该参数占用的堆栈内存块与对应的格式字符串规范所预期的内存块相匹配。

漏洞与风险

因为内存块大小与规范预期的大小相匹配,所以不会出现内存损坏的情况,但是可能导致得到非预期的输出。将代码移植到不同平台时也可能遇到问题。在此情况下,这些大小可能变得不同。

漏洞代码示例

复制
 void foo(FILE* f, char* pc, int i, char c, long l, struct SomeStruct ss) {
     fprintf(f, "%s", pc);
     fprintf(f, "%d", pc);// fprintf format mismatch: unexpected parameter type
     fprintf(f, "%10d", i);
     fprintf(f, "%hx", i);
     fprintf(f, "%c", l); // fprintf format mismatch: unexpected parameter type
     fprintf(f, "%p", i); // fprintf format mismatch: unexpected parameter type
 }

Klocwork 在第 3 行、第 6 行和第 7 行标记出错误,表明格式字符串规范和参数之间不匹配。格式规范显示第 3 行中预期整数,第 6 行中预期字符,而第 7 行中预期指针地址,但是这几行中提供的参数都与预期的不符。但是,因为没有出现内存不匹配的情况,所以该错误被视为 UNDESIRED 而非 BAD。相比之下,第 2 行、第 4 行和第 5 行是规范与参数相匹配的示例。

修正代码示例

复制
 void foo(FILE* f, char* pc, int i, char c, long l, struct SomeStruct ss) {
     fprintf(f, "%s", pc);
     fprintf(f, "%d", i);
     fprintf(f, "%10d", i);
     fprintf(f, "%hx", i);
     fprintf(f, "%c", c); 
     fprintf(f, "%p", pc); 
 }

在经修正的示例中,每一种格式规范和参数都相互对应。