[SRU][J][PATCH v4 11/11] kernfs: fix missing kernfs_iattr_rwsem locking

Ghadi Elie Rahme ghadi.rahme at canonical.com
Mon Sep 22 14:34:10 UTC 2025


From: Ian Kent <raven at themaw.net>

BugLink: https://bugs.launchpad.net/bugs/2125142

When the kernfs_iattr_rwsem was introduced a case was missed.

The update of the kernfs directory node child count was also protected
by the kernfs_rwsem and needs to be included in the change so that the
child count (and so the inode n_link attribute) does not change while
holding the rwsem for read.

Fixes: 9caf69614225 ("kernfs: Introduce separate rwsem to protect inode attributes.")
Cc: stable <stable at kernel.org>
Signed-off-by: Ian Kent <raven at themaw.net>
Reviewed-By: Imran Khan <imran.f.khan at oracle.com>
Acked-by: Miklos Szeredi <mszeredi at redhat.com>
Cc: Anders Roxell <anders.roxell at linaro.org>
Cc: Arnd Bergmann <arnd at arndb.de>
Cc: Minchan Kim <minchan at kernel.org>
Cc: Eric Sandeen <sandeen at sandeen.net>
Link: https://lore.kernel.org/r/169128520941.68052.15749253469930138901.stgit@donald.themaw.net
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
(cherry picked from commit 0559f63057f927d298d68294d6ff77ce09b99255)
Signed-off-by: Ghadi Elie Rahme <ghadi.rahme at canonical.com>
---
 fs/kernfs/dir.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index 32dc8435630d..6d23e5b9b34e 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -377,9 +377,11 @@ static int kernfs_link_sibling(struct kernfs_node *kn)
 	rb_insert_color(&kn->rb, &kn->parent->dir.children);
 
 	/* successfully added, account subdir number */
+	down_write(&kernfs_root(kn)->kernfs_iattr_rwsem);
 	if (kernfs_type(kn) == KERNFS_DIR)
 		kn->parent->dir.subdirs++;
 	kernfs_inc_rev(kn->parent);
+	up_write(&kernfs_root(kn)->kernfs_iattr_rwsem);
 
 	return 0;
 }
@@ -400,9 +402,11 @@ static bool kernfs_unlink_sibling(struct kernfs_node *kn)
 	if (RB_EMPTY_NODE(&kn->rb))
 		return false;
 
+	down_write(&kernfs_root(kn)->kernfs_iattr_rwsem);
 	if (kernfs_type(kn) == KERNFS_DIR)
 		kn->parent->dir.subdirs--;
 	kernfs_inc_rev(kn->parent);
+	up_write(&kernfs_root(kn)->kernfs_iattr_rwsem);
 
 	rb_erase(&kn->rb, &kn->parent->dir.children);
 	RB_CLEAR_NODE(&kn->rb);
-- 
2.34.1




More information about the kernel-team mailing list