"getenv...函数......可能不安全"--真的吗?

问题描述 投票:8回答:2

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

"getenv": 这个函数或变量可能不安全 考虑使用 _dupenv_s 来代替。要禁用弃用,请使用 _CRT_SECURE_NO_WARNINGS

问题:为什么从理论上讲,这不安全?

  • 为什么从理论上讲这是不安全的,而不是在其他平台上使用?
  • 它在Windows上的实践中是否不安全?
  • 假设我不是在写面向安全的代码--我应该禁用这个警告,还是真的开始别名一堆标准库函数?
visual-c++ compiler-warnings crt getenv c-standard-library
2个回答
9
投票

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标准......见。本报告.


-1
投票

getenv 和很多经典的C标准库一样,它的缺点是没有对字符串缓冲区的长度进行约束。这也是像缓冲区超限这样的安全bug经常起源的地方。

如果你看一下 getenv_s 你会看到它为返回的字符串长度提供了一个明确的约束。它推荐给所有的编码者。安全开发生命周期 的最佳实践,这也是为什么Visual C++会对不太安全的版本发出废弃警告。

请看 MSDN本博文

微软曾努力让CC++ ISO标准库中包含安全CRT。此处如上所述,其中一些已被批准列入附件K的C11。此处. 这也意味着 getenv_s 应该通过引用成为C++17标准库的一部分。也就是说,附件K被官方认为是符合标准的可选项。该 _s 这些函数的边界检查版本也仍然是一些 辩论 在CC++社区中。

© www.soinside.com 2019 - 2024. All rights reserved.