Race-free unlinking of directory entries

From: Pali RohÃr
Date: Wed Dec 20 2017 - 14:18:52 EST


Hi!

Linux kernel currently does not provide any race-free way for calling
unlink() syscall on file entry which points to opened file descriptor.

On the other hand Linux kernel already provides race-free way for
creating file entry by linkat() syscall with AT_EMPTY_PATH or
AT_SYMLINK_FOLLOW flags. unlinkat() does not.

There was already discussion about unlink issue in bugzilla:
https://bugzilla.kernel.org/show_bug.cgi?id=93441

Because file descriptor describes inode number which can be stored in
more directories as hard links, there is a proposed funlinkat() syscall
with following API:

int funlinkat(int fd, int dirfd, const char *pathname, int flags);

It should atomically check if file descriptor fd and pathname (according
to dirfd) are same, and if then just unlinkat(dirfd, pathname, flags).
If are not same, throw error.

What userspace application basically needs:

Open file, test it stat (or probably content) and based on test result
decide if file needs to be removed or not.

Or delete a file behind a file descriptor opened with O_PATH.

Both cases are currently not possible without introducing race condition
between open/stat and unlink. Between those two calls, some other
process can exchange files.

--
Pali RohÃr
pali.rohar@xxxxxxxxx