使用浮点数到字符串转换进行写入时可能发生溢出¶
ID: cpp/overrunning-write-with-float
Kind: problem
Security severity: 9.3
Severity: error
Precision: medium
Tags:
- reliability
- security
- external/cwe/cwe-120
- external/cwe/cwe-787
- external/cwe/cwe-805
Query suites:
- cpp-security-extended.qls
- cpp-security-and-quality.qls
程序执行缓冲区复制或写入操作,其中包含一个或多个浮点数到字符串的转换(例如 %f 格式说明符),如果输入值极端,则可能导致目标缓冲区溢出。除了会导致程序不稳定之外,还存在一些技术可以让攻击者利用此漏洞执行任意代码。
建议¶
始终控制缓冲区复制和缓冲区写入操作的长度。应使用 strncpy
而不是 strcpy
,使用 snprintf
而不是 sprintf
,在其他情况下,应优先考虑使用“n 变体”函数。
示例¶
void displayValue(double value)
{
char buffer[256];
// BAD: extreme values may overflow the buffer
sprintf(buffer, "%f", value);
MessageBox(hWnd, buffer, "A Number", MB_OK);
}
在本例中,对 sprintf
的调用包含 %f
格式说明符。虽然已允许使用 256 个字符的缓冲区,但这对于最极端的浮点数输入来说是不够的。例如,double 值 1e304(即 1 后面跟着 304 个零)的表示形式将溢出此长度的缓冲区。
要解决此问题,应进行三处更改:
使用预处理器定义来控制缓冲区的大小。
将对
sprintf
的调用替换为snprintf
,并将定义指定为要复制的最大长度。这将防止缓冲区溢出。考虑使用
%g
格式说明符而不是%f
。
参考资料¶
CERT C 编码标准:STR31-C. 确保为字符串分配的存储空间足以容纳字符数据和空终止符.
CERT C++ 编码标准:STR50-CPP. 确保为字符串分配的存储空间足以容纳字符数据和空终止符.
常见弱点枚举:CWE-120.
常见弱点枚举:CWE-787.
常见弱点枚举:CWE-805.