"getenv... function ... may be unsafe" - 真的吗?



我正在使用MSVC编译一些使用标准库函数的C代码,例如getenv()sprintf等,并设置了/W3警告。MSVC告诉我:

'

getenv':此函数或变量可能不安全。请考虑改用_dupenv_s。要禁用弃用,请使用 _CRT_SECURE_NO_WARNINGS

问题:

  • 为什么从理论上讲,这是不安全的 - 而不是在其他平台上使用?
  • 在实践中,它在Windows上不安全吗?
  • 假设我不是在编写面向安全的代码 - 我应该禁用此警告还是实际上开始为一堆标准库函数添加别名?

getenv()可能是不安全的,因为对同一函数的后续调用可能会使先前返回的指针无效。因此,诸如

char *a = getenv("A");
char *b = getenv("B");
/* do stuff with both a and b */

可能会中断,因为无法保证a此时仍然可用。

getenv_s() - 自 C11 起在 C 标准库中可用 - 通过立即将值复制到调用方提供的缓冲区中来避免这种情况,在该缓冲区中,调用方可以完全控制缓冲区的生存期。 dupenv_s()通过让调用方负责管理已分配缓冲区的生存期来避免这种情况。

然而,getenv_s的签名有些争议,该功能甚至可能在某个时候从 C 标准中删除......请参阅此报告。

getenv像许多经典的C标准库一样,没有限制字符串缓冲区长度。这就是缓冲区溢出等安全漏洞通常的来源。

如果您查看getenv_s您会发现它对返回字符串的长度提供了显式绑定。建议将安全开发生命周期最佳做法用于所有编码,这就是 Visual C++ 对安全性较低的版本发出弃用警告的原因。

请参阅 MSDN 和此博客文章

Microsoft努力让 C/C++ ISO 标准库在此处包含安全 CRT,其中一些已批准用于 C11 附录 K,如此处所述。这也意味着getenv_s应该通过引用成为 C++17 标准库的一部分。也就是说,附件 K 被正式认为是可选的一致性。这些函数的_s边界检查版本仍然是 C/C++ 社区中一些争论的主题。

相关内容

  • 没有找到相关文章

最新更新