我正在使用MSVC编译一些使用标准库函数的C代码,例如getenv()
,sprintf
和其他函数,/W3
设置为警告。 MSVC告诉我:
'getenv':此函数或变量可能不安全。请考虑使用_dupenv_s。要禁用弃用,请使用_CRT_SECURE_NO_WARNINGS
问题:
答案 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 ++为安全性较低的版本发出弃用警告的原因。
微软努力让C / C ++ ISO标准库包含安全CRT here,其中一些已被批准用于C11附件K [{3}}。这也意味着
getenv_s
应该通过引用成为C ++ 17标准库的一部分。也就是说,附件K被正式视为可选的一致性。这些函数的_s
边界检查版本仍然是C / C ++社区中某些here的主题。