Fortify 表明这是一个越界读取:
if (strncmp("test string", "less than 32 char", 32) == 0)
{
...
}
它表示该函数从less than 32 char
.
strncmp
如果超过 32 个字符并且第二个字符串小于 32 个字符,是否真的有发现?
出于性能原因,标准字符串函数的实现通常会以自然对齐的寄存器宽度块处理数据。这可能会导致读取访问超出源数据对象的末尾,但对齐可确保代码的行为与内存异常方面的简单实现完全相同。每个宽访问都包含在一个页面中,并且没有任何页面被触及,而这些页面也不会被逐字节实现触及。
我会声称这样的实现被 C 的 as-if 规则所涵盖,也就是说,它们的行为与“好像”它们遵循抽象的功能规范一样。
这种优化实现的一个例子是OpenSolaris's strcmp()
for SPARC v8。这是我大约十五年前编写的代码,以及其他性能优化的字符串函数。
然而,各种内存检查工具都会抱怨这样的代码,因为它的使用可能导致访问超出分配的数据对象的限制,即使越界读取访问在设计上是无害的。
TL;DR -strncmp()
将继续比较字符串元素,直到字符串或 32 个元素(字符)结束,以较少者为准。
A( ny )字符串始终以 null 结尾,并且在遇到 null 终止符时,不会执行进一步的比较。您的代码是安全的。
引用C11
,第 7.24.4.4 章(强调我的)
int strncmp(const char *s1, const char *s2, size_t n);
该
strncmp
函数将所指向的数组与 所指向的数组中的多个n
字符(不比较空字符后的字符)进行比较。s1
s2
你有完全有效的代码。
您的编译器正在生成错误的目标代码,或者 fortify 正在报告误报。
我怀疑是编译器生成了错误的代码。这将产生太多问题,并且很快就会被检测到并修复。
fortify 很可能报告了误报。