FAILED: patch "[PATCH] configfs: unhash the dentry before dropping the item in rmdir" failed to apply to 6.1-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.1-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]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.1.y
git checkout FETCH_HEAD
git cherry-pick -x f06c2d26d1999d37e93299db0ecead04ca7d0b9f
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026091658-data-urchin-e973@gregkh' --subject-prefix 'PATCH 6.1.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From f06c2d26d1999d37e93299db0ecead04ca7d0b9f Mon Sep 17 00:00:00 2001
From: Vasileios Almpanis <[email protected]>
Date: Thu, 30 Jul 2026 11:30:25 +0200
Subject: [PATCH] configfs: unhash the dentry before dropping the item in rmdir
configfs_get_config_item() treats a hashed dentry as proof that sd->s_element is a live config_item. configfs_rmdir() breaks that:simple_rmdir() leaves the dentry hashed, the last reference to the item is dropped right after, and the dentry is only unhashed by d_delete() once ->rmdir() has returned. configfs_symlink() resolves its target holding no lock on it, so get_target() can land in that window:
BUG: KASAN: slab-use-after-free in config_item_get+0x26/0x90 get_target fs/configfs/symlink.c:128 [inline] configfs_symlink+0x4ab/0x1030 fs/configfs/symlink.c:185
Unhash in configfs_remove_dir(), while the item is still guaranteed to be there. A reference obtained just before that stays harmless, as create_link() rechecks CONFIGFS_USET_DROPPING, already set by configfs_detach_prep(). Both configfs_unregister_subsystem() paths d_drop() after detaching, so this only makes rmdir match them.
fs/configfs/dir.c +9 -0
@@ -416,6 +416,15 @@ static void configfs_remove_dir(struct dentry *d)if (d_really_is_positive (d)) {if (unlikely (simple_rmdir (d_inode (parent), d)))pr_warn ("remove_dir (%pd): attributes remain" , d); +else +/* +* configfs_get_config_item() takes a hashed dentry as +* proof that ->s_element is still alive. Our caller +* is about to drop the last reference to the item and +* the VFS will not unhash until after we return, so +* unhash it here. +*/ +d_drop (d); }pr_debug (" o %pd removing done (%d)\n" , d,d_count (d));
Sasha Levin
maintainerPATCH 1/1 configfs: unhash the dentry before dropping the item in rmdir
From: Vasileios Almpanis <[email protected]>
[ Upstream commit f06c2d26d1999d37e93299db0ecead04ca7d0b9f ]
configfs_get_config_item() treats a hashed dentry as proof that sd->s_element is a live config_item. configfs_rmdir() breaks that:simple_rmdir() leaves the dentry hashed, the last reference to the item is dropped right after, and the dentry is only unhashed by d_delete() once ->rmdir() has returned. configfs_symlink() resolves its target holding no lock on it, so get_target() can land in that window:
BUG: KASAN: slab-use-after-free in config_item_get+0x26/0x90 get_target fs/configfs/symlink.c:128 [inline] configfs_symlink+0x4ab/0x1030 fs/configfs/symlink.c:185
Unhash in configfs_remove_dir(), while the item is still guaranteed to be there. A reference obtained just before that stays harmless, as create_link() rechecks CONFIGFS_USET_DROPPING, already set by configfs_detach_prep(). Both configfs_unregister_subsystem() paths d_drop() after detaching, so this only makes rmdir match them.
--- fs/configfs/dir.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
fs/configfs/dir.c +11 -2
@@ -395,8 +395,17 @@ static void remove_dir(struct dentry * d)configfs_remove_dirent (d); -if (d_really_is_positive (d)) -simple_rmdir (d_inode (parent),d); +if (d_really_is_positive (d)) { +if (!simple_rmdir (d_inode (parent), d)) +/* +* configfs_get_config_item() takes a hashed dentry as +* proof that ->s_element is still alive. Our caller +* is about to drop the last reference to the item and +* the VFS will not unhash until after we return, so +* unhash it here. +*/ +d_drop (d); + }pr_debug (" o %pd removing done (%d)\n" , d,d_count (d));
Signature · 1 line
2.53.0