]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
fsnotify: invalidate dcache before IN_DELETE event
authorAmir Goldstein <amir73il@gmail.com>
Thu, 20 Jan 2022 21:53:04 +0000 (23:53 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 10 Apr 2024 14:19:00 +0000 (16:19 +0200)
[ Upstream commit a37d9a17f099072fe4d3a9048b0321978707a918 ]

Apparently, there are some applications that use IN_DELETE event as an
invalidation mechanism and expect that if they try to open a file with
the name reported with the delete event, that it should not contain the
content of the deleted file.

Commit 49246466a989 ("fsnotify: move fsnotify_nameremove() hook out of
d_delete()") moved the fsnotify delete hook before d_delete() so fsnotify
will have access to a positive dentry.

This allowed a race where opening the deleted file via cached dentry
is now possible after receiving the IN_DELETE event.

To fix the regression, create a new hook fsnotify_delete() that takes
the unlinked inode as an argument and use a helper d_delete_notify() to
pin the inode, so we can pass it to fsnotify_delete() after d_delete().

Backporting hint: this regression is from v5.3. Although patch will
apply with only trivial conflicts to v5.4 and v5.10, it won't build,
because fsnotify_delete() implementation is different in each of those
versions (see fsnotify_link()).

A follow up patch will fix the fsnotify_unlink/rmdir() calls in pseudo
filesystem that do not need to call d_delete().

Link: https://lore.kernel.org/r/20220120215305.282577-1-amir73il@gmail.com
Reported-by: Ivan Delalande <colona@arista.com>
Link: https://lore.kernel.org/linux-fsdevel/YeNyzoDM5hP5LtGW@visor/
Fixes: 49246466a989 ("fsnotify: move fsnotify_nameremove() hook out of d_delete()")
Cc: stable@vger.kernel.org # v5.3+
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>
[ cel: adjusted to apply on v5.15.y ]
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
include/linux/fsnotify.h

index c80f448b9b0f22e7bcd21ff3981b60dfbdbb423b..bb8467cd11ae28eb795db5eb17d4b78774da61ca 100644 (file)
@@ -240,7 +240,8 @@ static inline void fsnotify_delete(struct inode *dir, struct inode *inode,
        if (S_ISDIR(inode->i_mode))
                mask |= FS_ISDIR;
 
-       fsnotify_name(dir, mask, inode, &dentry->d_name, 0);
+       fsnotify_name(mask, inode, FSNOTIFY_EVENT_INODE, dir, &dentry->d_name,
+                     0);
 }
 
 /**