C++ tmpnam警告说这是危险的

C++ tmpnam警告说这是危险的,c++,temporary-files,C++,Temporary Files,我收到这个警告,说tmpnam是危险的,但我更愿意使用它,因为它可以像在Windows和Linux中一样使用。我想知道为什么它会被认为是危险的(我猜这是因为它可能被误用,而不是因为它实际上工作不正常)。来自tmpnam手册: 函数每次调用时都会生成一个不同的字符串,最多生成TMP_MAX次。如果调用次数超过TMP_MAX次,则行为由实现定义 尽管tmpnam()生成的名称难以猜测,但在tmpnam()返回路径名和程序打开路径名之间,另一个程序可能会使用open(2)创建该路径名,或将其作为符号链

我收到这个警告,说tmpnam是危险的,但我更愿意使用它,因为它可以像在Windows和Linux中一样使用。我想知道为什么它会被认为是危险的(我猜这是因为它可能被误用,而不是因为它实际上工作不正常)。

来自tmpnam手册:

函数每次调用时都会生成一个不同的字符串,最多生成TMP_MAX次。如果调用次数超过TMP_MAX次,则行为由实现定义

尽管tmpnam()生成的名称难以猜测,但在tmpnam()返回路径名和程序打开路径名之间,另一个程序可能会使用open(2)创建该路径名,或将其作为符号链接创建。这可能导致安全漏洞。为了避免这种可能性,请使用open(2)O_EXCL标志打开路径名。或者更好地使用mkstemp(3)或tmpfile(3)

Mktemp确实创建了该文件,因此您可以确信它可以工作,而tmpnam返回一个可能已经存在的名称。

从tmpnam(3)手册页:

虽然tmpnam()生成的名称很难猜测,但在 tmpnam()返回一个路径名,当程序打开它时,另一个程序可能会创建该路径 使用open(2)命名,或将其创建为符号链接。这可能导致安全漏洞。为了避免这种可能性—— 连接时,使用open(2)O_EXCL标志打开路径名。或者更好地使用mkstemp(3)或tmpfile(3)


如果您谈到MSVC的编译器警告:

 These functions are deprecated because more secure versions are available;
 see tmpnam_s, _wtmpnam_s.
()


否则,请阅读手册页上关于此函数缺点的说明。它主要是关于第二个进程创建与您的进程刚才完全相同的文件名。

如果您想在多个平台上使用相同的符号,请使用宏定义TMPNAM。只要选择具有相同接口的更安全的函数,就可以在这两个接口上使用它。无论如何,您的代码中有条件编译,对吗?

该函数很危险,因为您负责分配一个足够大的缓冲区来处理
tmpnam()
将要写入该缓冲区的字符串。如果分配的缓冲区太小,
tmpnam()
无法知道这一点,并且会使缓冲区溢出(造成严重破坏)
tmpnam_s()
(MS的安全版本)要求您传递缓冲区的长度,因此
tmpnam_s
知道何时停止。

您可以添加一些上下文吗?谁声称这很危险?
tmpname
完全是变量名、文件名、源文件名还是其他什么?不是所有人都有通灵能力。@sbi:
tmpnam
是一个标准的C库函数。@Nathon我实际上是在谈论gcc和msvc,我只是想知道说它危险的理由是什么@sbi我想我应该提到这是一个标准的Lib函数。如果黑客有你的代码。他可以在您的代码调用tmpnam()之后,但在您打开文件之前附加调试器并暂停程序。然后,攻击者将修改文件系统,使其能够访问该文件,然后让您的代码继续。攻击者现在可以完全访问您的tmp数据。或者,如果使用tmpfile(),则不会在代码中打开此漏洞,因为当代码位于操作系统的特权部分时,攻击者很难阻止代码。有一个处理器前常量L_tmpnam,它指定了实现将写入的最大长度(或者在单线程程序中,您可以使用空指针,在这种情况下,它将使用静态缓冲区)。因此,这是一个容易避免的问题。危险的部分来自创建文件名和随后创建文件本身之间可能存在的争用情况。大多数安全漏洞都很容易避免。(你的回答引用了一个简单的方法来避免你描述的问题)。如果你不遵守规则,我描述的问题更有可能发生。(这也是tmpnam_s()修复的问题,所以这显然是他们正在思考的问题)使用
mktemp
仅适用于需要
tmpnam\u s
\wtmpnam\u s
的Windows。因此,独立于平台的版本并不容易。