"getenv... function ... may be unsafe" - 真的吗?
"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
与许多经典 C 标准库一样,没有限制字符串缓冲区长度。这就是缓冲区溢出等安全漏洞的来源。
如果您查看 getenv_s
,您会发现它对返回字符串的长度提供了明确的限制。 Security Development Lifecycle 最佳实践推荐所有编码使用它,这就是为什么 Visual C++ 会针对安全性较低的版本发出弃用警告。
见MSDN and this blog post
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.
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 标准中删除...参见this report.
我正在使用 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
与许多经典 C 标准库一样,没有限制字符串缓冲区长度。这就是缓冲区溢出等安全漏洞的来源。
如果您查看 getenv_s
,您会发现它对返回字符串的长度提供了明确的限制。 Security Development Lifecycle 最佳实践推荐所有编码使用它,这就是为什么 Visual C++ 会针对安全性较低的版本发出弃用警告。
见MSDN and this blog post
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.
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 标准中删除...参见this report.