“'getenv':这个函数或变量可能不安全。” - 真的吗?

时间:2018-02-01 17:40:08

标签: visual-c++ compiler-warnings crt getenv c-standard-library

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

  

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

问题:

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

2 个答案:

答案 0 :(得分:5)

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

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

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

getenv_s()通过立即将值复制到调用者提供的缓冲区来避免这种情况,调用者可以完全控制缓冲区的生命周期。 dupenv_s()通过使调用者负责管理分配的缓冲区的生命周期来避免这种情况。

答案 1 :(得分:0)

getenv通过不绑定字符串缓冲区长度而受到许多经典C标准库的影响。这就是缓冲区溢出等安全漏洞通常来自的地方。

如果你看getenv_s,你会看到它提供了返回字符串长度的显式界限。它推荐用于Security Development Lifecycle最佳实践的所有编码,这就是Visual C ++为安全性较低的版本发出弃用警告的原因。

请参阅MSDNthis blog post

  

微软努力让C / C ++ ISO标准库包含安全CRT here,其中一些已被批准用于C11附件K [{3}}。这也意味着getenv_s应该通过引用成为C ++ 17标准库的一部分。也就是说,附件K被正式视为可选的一致性。这些函数的_s边界检查版本仍然是C / C ++社区中某些here的主题。