关于视觉c:” getenv…函数……可能不安全”-真的吗?

“getenv… function … may be unsafe” - really?

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

'getenv': This function or variable may be unsafe. Consider using _dupenv_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS

问题:

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


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

的用法

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

可能会中断,因为不能保证a那时仍然可以使用。

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

但是,getenv_s的签名有些争议,甚至有时甚至可以从C标准中删除该功能...请参阅此报告。


getenv像不受限制的字符串缓冲区长度一样,受到了许多经典的C标准库的困扰。这就是诸如缓冲区溢出之类的安全漏洞通常源自的地方。

如果您查看getenv_s,您会看到它为返回的字符串的长度提供了明确的界限。安全开发生命周期最佳实践建议对所有编码进行推荐,这就是为什么Visual C会针对较不安全的版本发出弃用警告的原因。

请参阅MSDN和此博客文章

There was an effort by Microsoft to get the C/C++ ISO Standard Library to include the Secure CRT here, some of which was approved for C11 Annex K as noted here. That also means that getenv_s should be part of the C++17 Standard Library by reference. That said, Annex K is officially considered optional for conformance. The _s bounds-checking versions of these functions are also still a subject of some debate in the C/C++ community.