C mkstemp()-关闭描述符并重新打开它是否安全?

C mkstemp()-关闭描述符并重新打开它是否安全?,c,posix,C,Posix,使用mkstemp()生成临时文件名时,立即调用mkstemp()返回的文件描述符上的close()是否安全,将mkstemp()生成的文件名存储在某个位置,并使用它(稍后)再次打开文件以写入临时文件?或者,当我调用close()时,这个临时文件名会再次可用吗 我问这个问题的原因是我想知道为什么mkstemp()会返回一个文件描述符。如果立即关闭()描述符是安全的,为什么它会返回描述符呢?mkstemp()可以自己关闭它,然后给我一个文件名 否。在您使用mkstemp()创建文件和重新打开文件之

使用mkstemp()生成临时文件名时,立即调用mkstemp()返回的文件描述符上的close()是否安全,将mkstemp()生成的文件名存储在某个位置,并使用它(稍后)再次打开文件以写入临时文件?或者,当我调用close()时,这个临时文件名会再次可用吗


我问这个问题的原因是我想知道为什么mkstemp()会返回一个文件描述符。如果立即关闭()描述符是安全的,为什么它会返回描述符呢?mkstemp()可以自己关闭它,然后给我一个文件名

否。在您使用
mkstemp()
创建文件和重新打开文件之间,您的对手可能已经删除了您创建的文件,并在其位置放置了一个指向其他地方的符号链接。这是一个TOCTOU-检查时间、使用时间-漏洞,如果您保持文件描述符打开,则使用
mkstemp()
可以在很大程度上避免此漏洞

一旦关闭文件描述符,在一个充满敌意的环境中,所有的赌注都将被取消

请注意,即使您保持文件描述符打开,对手也可能会删除该文件,或重命名它,然后在其位置创建自己的文件(符号链接,目录)。文件描述符仍然有效。您可以使用
stat()
获取名称信息和
fstat()
获取文件描述符信息,如果这两个字段匹配(
st_dev
st_ino
字段),那么您可能仍然可以。如果它们不同,则表示有人对该文件进行了修改-如果您重命名该文件,则可能是重命名了他们的文件,而不是您创建的文件

虽然最初由
mkstemp()
创建的文件仍然存在,但不会重新生成名称。通常,对
mkstemp()
的连续调用无论如何都会创建不同的名称,但在创建时保证名称是唯一的(有关详细信息,请参阅
O_exc
标志)

如果您想知道,没有-没有一种方法可以将名称与文件描述符相关联(没有假设的
intflink(intfd,constchar*name)
system调用)。不久前,在一个Stack Exchange站点上有一个关于这一点的问题,答案肯定是否定的,涉及到Linux内核邮件列表等等。一个这样的问题是,但我认为这个问题也有一个更彻底的版本。

该函数专门使用描述符而不是文件名,以避免通常与它的前辈(例如)相关的争用条件。事实上,“mkstemp”中的“s”表示“安全”,因为竞争条件可能是漏洞的来源(例如,如果您使用临时文件存储JIT代码,并且有人在打开该文件之前猜测/跺脚该文件,可能会导致应用程序加载/运行提供的代码,而不是程序生成的代码)


一旦关闭描述符,就不会阻止其他应用程序使用相同的名称编写文件,因此请不要这样做。只要需要临时文件,您就应该保留描述符(并在程序不再使用临时文件时关闭描述符)。

Ok,这是一个安全问题。但是,如果对mkstemp()的前一次调用的文件名已关闭(),对mkstemp()的后续调用是否会返回完全相同的文件名?
mkstemp()
如果原始文件已被删除,则只能返回相同的名称两次;如果它仍然存在,它将不再返回相同的名称。好的,谢谢。这正是我想知道的:)谢谢。当然,我知道另一个程序关闭后可能会更改文件的风险,但我可以承受这种风险。我只是想知道是否会发生甚至mkstemp()再次返回相同的名称的情况,但当时的情况似乎并非如此。