Simulating O_NOFOLLOW (2): Is this other approach safe?
- by Daniel Trebbien
As a follow-up question to this one, I thought of another approach which builds off of @caf's answer for the case where I want to append to file name and create it if it does not exist.
Here is what I came up with:
Create a temporary directory with mode 0700 in a system temporary directory on the same filesystem as file name.
Create an empty, temporary, regular file (temp_name) in the temporary directory (only serves as placeholder).
Open file name for reading only, just to create it if it does not exist. The OS may follow name if it is a symbolic link; I don't care at this point.
Make a hard link to name at temp_name (overwriting the placeholder file). If the link call fails, then exit. (Maybe someone has come along and removed the file at name, who knows?)
Use lstat on temp_name (now a hard link). If S_ISLNK(lst.st_mode), then exit.
open temp_name for writing, append (O_WRONLY | O_APPEND).
Write everything out. Close the file descriptor.
unlink the hard link.
Remove the temporary directory.
(All of this, by the way, is for an open source project that I am working on. You can view the source of my implementation of this approach here.)
Is this procedure safe against symbolic link attacks? For example, is it possible for a malicious process to ensure that the inode for name represents a regular file for the duration of the lstat check, then make the inode a symbolic link with the temp_name hard link now pointing to the new, symbolic link?
I am assuming that a malicious process cannot affect temp_name.