CodeQL 文档

使用浮点数到字符串转换进行写入时可能发生溢出

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

点击查看 CodeQL 存储库中的查询

程序执行缓冲区复制或写入操作,其中包含一个或多个浮点数到字符串的转换(例如 %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

参考资料

  • ©GitHub, Inc.
  • 条款
  • 隐私