FAILED: patch "[PATCH] fsnotify: invalidate dcache before IN_DELETE event" failed to apply to 5.10-stable tree
[email protected]
maintainerThe patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From a37d9a17f099072fe4d3a9048b0321978707a918 Mon Sep 17 00:00:00 2001
From: Amir Goldstein <[email protected]>
Date: Thu, 20 Jan 2022 23:53:04 +0200
Subject: [PATCH] fsnotify: invalidate dcache before IN_DELETE event
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().
fs/btrfs/ioctl.c +2 -4
@@ -3086,10 +3086,8 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,btrfs_inode_lock (inode,0 ); err =btrfs_delete_subvolume (dir, dentry);btrfs_inode_unlock (inode,0 ); -if (!err) { -fsnotify_rmdir (dir, dentry); -d_delete (dentry); - } +if (!err) +d_delete_notify (dir, dentry); out_dput:dput (dentry);
fs/namei.c +5 -5
@@ -3974,13 +3974,12 @@ int vfs_rmdir(struct user_namespace *mnt_userns, struct inode *dir, dentry->d_inode->i_flags |=S_DEAD ;dont_mount (dentry);detach_mounts (dentry); -fsnotify_rmdir (dir, dentry); out:inode_unlock (dentry->d_inode);dput (dentry);if (!error) -d_delete (dentry); +d_delete_notify (dir, dentry);return error; }EXPORT_SYMBOL (vfs_rmdir);
@@ -4102,7 +4101,6 @@ int vfs_unlink(struct user_namespace *mnt_userns, struct inode *dir,if (!error) {dont_mount (dentry);detach_mounts (dentry); -fsnotify_unlink (dir, dentry); } } }
@@ -4110,9 +4108,11 @@ int vfs_unlink(struct user_namespace *mnt_userns, struct inode *dir,inode_unlock (target);/* We don't d_delete() NFS sillyrenamed files--they still exist. */ -if (!error && !(dentry->d_flags &DCACHE_NFSFS_RENAMED )) { +if (!error && dentry->d_flags &DCACHE_NFSFS_RENAMED ) { +fsnotify_unlink (dir, dentry); + }else if (!error) {fsnotify_link_count (target); -d_delete (dentry); +d_delete_notify (dir, dentry); }return error;
include/linux/fsnotify.h +43 -6
69 lines not on this page · raw message
Amir Goldstein
reviewerQuoted 7 lines · On Sat, Jan 29, 2022 at 2:57 PM <[email protected]> wrote:
The patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
5.10 backport patch attached.
Thanks,
Amir.
From aabf638dedacdc362b5c46414a13105f5affedb6 Mon Sep 17 00:00:00 2001
From: Amir Goldstein <[email protected]>
Date: Thu, 20 Jan 2022 23:53:04 +0200
Subject: [PATCH 5.10] fsnotify: invalidate dcache before IN_DELETE event
commit a37d9a17f099072fe4d3a9048b0321978707a918 upstream.
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().
--- fs/btrfs/ioctl.c | 6 ++---- fs/namei.c | 10 +++++----- include/linux/fsnotify.h | 48 ++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 49 insertions(+), 15 deletions(-)
fs/btrfs/ioctl.c +2 -4
@@ -3103,10 +3103,8 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,inode_lock (inode); err =btrfs_delete_subvolume (dir, dentry);inode_unlock (inode); -if (!err) { -fsnotify_rmdir (dir, dentry); -d_delete (dentry); - } +if (!err) +d_delete_notify (dir, dentry); out_dput:dput (dentry);
fs/namei.c +5 -5
@@ -3709,13 +3709,12 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) dentry->d_inode->i_flags |=S_DEAD ;dont_mount (dentry);detach_mounts (dentry); -fsnotify_rmdir (dir, dentry); out:inode_unlock (dentry->d_inode);dput (dentry);if (!error) -d_delete (dentry); +d_delete_notify (dir, dentry);return error; }EXPORT_SYMBOL (vfs_rmdir);
@@ -3825,7 +3824,6 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode **delegateif (!error) {dont_mount (dentry);detach_mounts (dentry); -fsnotify_unlink (dir, dentry); } } }
@@ -3833,9 +3831,11 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode **delegateinode_unlock (target);/* We don't d_delete() NFS sillyrenamed files--they still exist. */ -if (!error && !(dentry->d_flags &DCACHE_NFSFS_RENAMED )) { +if (!error && dentry->d_flags &DCACHE_NFSFS_RENAMED ) { +fsnotify_unlink (dir, dentry); + }else if (!error) {fsnotify_link_count (target); -d_delete (dentry); +d_delete_notify (dir, dentry); }return error;
include/linux/fsnotify.h +42 -6
68 lines not on this page · raw message
Signature · 1 line
2.16.5
Quoted 7 lines · Amir Goldstein
Quoted 4 lines · On Sat, Jan 29, 2022 at 2:57 PM <[email protected]> wrote:
The patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.5.10 backport patch attached.
Just to confirm once more, I tested this patch along with the 5.10 backport of "fsnotify: fix fsnotify hooks in pseudo filesystems" on our kernel, and we don't see the problem that we originally reported with our application anymore.
Thanks again for your help on this Amir,
Signature · 2 lines
Ivan Delalande Arista Networks