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

时间:2014-12-28 21:35:29

标签: c posix

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

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

2 个答案:

答案 0 :(得分:6)

没有。在您使用mkstemp()创建文件的时间和重新打开文件的时间之间,您的对手可能已删除您创建的文件,并将符号链接放在指向其他位置的位置。这是一个TOCTOU - 检查时间,使用时间 - 使用mkstemp()的漏洞很大程度上避免了,只要你保持文件描述符打开。

关闭文件描述符后,所有投注都会在充满敌意的环境中关闭。

请注意,即使您保持文件描述符处于打开状态,攻击者也可能会删除该文件,或重命名该文件,然后在其位置创建自己的文件(符号链接,目录)。文件描述符仍然有效。您可以使用stat()获取名称信息,使用fstat()获取文件描述符信息,如果两者匹配(st_devst_ino字段),那么您&# 39;可能还可以。如果它们不同,有人会找到该文件 - 如果你重命名它,你可能会重命名他们的文件而不是你创建的文件。

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

如果你想知道,不 - 没有办法将名称与文件描述符相关联(没有假设的int flink(int fd, const char *name)系统调用)。不久前在Stack Exchange网站上有一个问题,答案肯定是否定的,引用了Linux Kernel邮件列表等等。其中一个问题是Is it possible to recreate a file from an opened file descriptor?,但我认为问题还有一个更彻底的版本。

答案 1 :(得分:4)

mkstemp函数专门使用描述符而不是文件名来避免通常与其前身相关的竞争条件,例如mktemp。事实上," s"在" mkstemp"意味着"安全",因为竞争条件可能是漏洞的来源(例如,如果您使用临时文件存储JIT代码,并且有人在您打开文件之前猜测/踩踏文件可能会导致您的应用程序加载/运行提供的代码而不是程序生成的代码。

关闭描述符后,没有什么可以阻止其他应用程序编写具有相同名称的文件,所以请不要这样做。只要需要临时文件,就应保留描述符(并在程序不再使用临时文件后关闭描述符)。