Mkstemp () - is it safe to close a handle and reopen it again?

When creating a temporary filename using mkstemp (), it is safe to immediately call close () on the file descriptor returned by mkstemp (), store the filename generated by mkstemp () somewhere, and use it (pretty much later), so that again to open a file to write a temporary file? Or will this temporary filename become available again as soon as I call close () on it?

The reason I am asking is because I am wondering why mkstemp () returns a file descriptor at all. If it is safe to close () the handle immediately, why does it return the handle at all? mkstemp () can close it on its own and just give me the filename.

+3


source to share


2 answers


Not. Between the time you use mkstemp()

to create the file and the time it was reopened, your adversary may have deleted the file you created and placed a symbolic link in its place pointing to a different location. This is TOCTOU - check time, use time - a vulnerability that mkstemp()

is largely prevented from exploitation if you keep the file descriptor open.

Once you close the file descriptor, all bets are disabled in a fairly aggressive environment.

Note that even if you keep the file descriptor open, the adversary can delete the file or rename it and then create their own file (symlink, directory) in place. The file descriptor remains valid. You can use stat()

to get name information and fstat()

to get file descriptor information and if the two match fields ( st_dev

and st_ino

) then you are probably still fine. If they are different, someone is trapped in the file - if you rename it, you can rename your file, not the one you created.



As long as the file created with mkstemp()

still exists, the name will not be restored. In general, successive calls mkstemp()

will create different names anyway, but the name is guaranteed to be unique at the time of creation (see Flag O_EXCL

for open()

).

And just in case you're wondering, no - there is no way to associate a name with a file descriptor (no system call int flink(int fd, const char *name)

). A question about this on one of the Stack Exchange sites a while ago and the answer was definitely no, referring to the Linux Kernel mailing list and so on. One such question is - Is it possible to recreate a file from an open file descriptor? , but I think there was a more complete version of the question.

+6


source


The mkstemp function specifically uses descriptors instead of filenames to avoid race conditions that are usually associated with its predecessors such as mktemp . In fact, the "s" in "mkstemp" means "safe" as a race condition can be a source of vulnerability (for example, if you use a temporary file to store JIT code, for example, and someone guesses / stomps on the file before you open it, this could cause your application to load / run the provided code, not the code your program generates).



Once the handle is closed, nothing prevents another application from writing the file with the same name, so please don't do that. You must keep the handle for as long as the temporary file is needed (and close the handle as soon as the temporary file is no longer in use by your program).

+4


source







All Articles