unixfilesystemssystem-callsunlinkinode

Is there a safeunlink syscall in Unix?


There is an unlink syscall in Unix, which takes a path as argument, and unlinks that path from inode.

Suppose this case. I will open a file, access the contents, and then decide that it should be unlinked. By this time, a different process has replaced that path with a different file for some reason. Now if I call unlink with that path, it will unlink the wrong file, and probably confusing the other process.

Hence, is there way where I can pass the inode number along with the path to (safe)unlink syscall so that it can atomically check if the path refers to the same inode and then unlink, if not report an errno or do a no-op?

Is there a way to do that in Unix? If not why is it left out? Is such a syscall not necessary for some reason? Can it be emulated using combination of other syscalls? Is it missed out by mistake?


Solution

  • As far as I'm aware, there's no interface to unlink() functionality that avoids the race condition described here.

    Filesystem operations in POSIX have always been at risk of name substitution; Linux added openat(), unlinkat() and more to mitigate these, but never added an interface that checks the final name matches an expected inode.

    I don't think there's a way to get this atomic unlink-if-matching behaviour without adding to the syscall API, because anything we do from user-space here is subject to races. The only possibility is if your target system supports mandatory access locks on directories, and has an equivalent of unlinkat().