FAILED: patch "[PATCH] smb: client: pin DFS superblock in iterator callback" failed to apply to 5.10-stable tree
Subsystems (2)
[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]>.
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-5.10.y
git checkout FETCH_HEAD
git cherry-pick -x d806d5a85dcbe2a0f181b2f0f9f61ddfbefa1818
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026091644-blouse-acre-e296@gregkh' --subject-prefix 'PATCH 5.10.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From d806d5a85dcbe2a0f181b2f0f9f61ddfbefa1818 Mon Sep 17 00:00:00 2001
From: Karl Mehltretter <[email protected]>
Date: Wed, 2 Sep 2026 20:28:14 +0200
Subject: [PATCH] smb: client: pin DFS superblock in iterator callback
tcon_super_cb() stores a raw superblock pointer, but __cifs_get_super() takes its active reference only after iterate_supers_type() has dropped s_umount and its passive reference. Concurrent DFS automount expiry can therefore free the superblock before cifs_sb_active() uses it.
A deterministic KASAN test reproduces the race as:
BUG: KASAN: slab-use-after-free in cifs_sb_active+0x77/0x80
The same test passes with this change applied.
Take the active reference in the callback while iterate_supers_type() still holds s_umount shared. cifs_put_tcp_super() remains the matching release.
fs/smb/client/misc.c +8 -9
@@ -891,8 +891,14 @@ static void tcon_super_cb(struct super_block *sb, void *arg) t1->ses->dfs_root_ses == t2->ses->dfs_root_ses) && t1->ses->server == t2->ses->server && t2->origin_fullpath && - dfs_src_pathname_equal(t2->origin_fullpath, t1->origin_fullpath)) + dfs_src_pathname_equal(t2->origin_fullpath, t1->origin_fullpath)) { +/* +* Take the active reference while iterate_supers_type() still +* holds s_umount shared. +*/ +cifs_sb_active (sb); sd->sb = sb; + }spin_unlock (&t2->tc_lock); }
@@ -909,15 +915,8 @@ static struct super_block *__cifs_get_super(void (*f)(struct super_block *, voidfor (; *fs_type; fs_type++) {iterate_supers_type (*fs_type, f, &sd); -if (sd.sb) { -/* -* Grab an active reference in order to prevent automounts (DFS links) -* of expiring and then freeing up our cifs superblock pointer while -* we're doing failover. -*/ -cifs_sb_active (sd.sb); +if (sd.sb)return sd.sb; - } }pr_warn_once ("%s: could not find dfs superblock\n" , __func__);return ERR_PTR (-EINVAL );
Sasha Levin
maintainerPATCH 1/1 smb: client: pin DFS superblock in iterator callback
From: Karl Mehltretter <[email protected]>
[ Upstream commit d806d5a85dcbe2a0f181b2f0f9f61ddfbefa1818 ]
tcon_super_cb() stores a raw superblock pointer, but __cifs_get_super() takes its active reference only after iterate_supers_type() has dropped s_umount and its passive reference. Concurrent DFS automount expiry can therefore free the superblock before cifs_sb_active() uses it.
A deterministic KASAN test reproduces the race as:
BUG: KASAN: slab-use-after-free in cifs_sb_active+0x77/0x80
The same test passes with this change applied.
Take the active reference in the callback while iterate_supers_type() still holds s_umount shared. cifs_put_tcp_super() remains the matching release.
--- fs/cifs/misc.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-)
fs/cifs/misc.c +8 -9
@@ -1054,8 +1054,14 @@ static void tcp_super_cb(struct super_block *sb, void *arg) cifs_sb =CIFS_SB (sb); tcon =cifs_sb_master_tcon (cifs_sb); -if (tcon->ses->server == server) +if (tcon->ses->server == server) { +/* +* Take the active reference while iterate_supers_type() still +* holds s_umount shared. +*/ +cifs_sb_active (sb); sd->sb = sb; + } } static struct super_block *__cifs_get_super(void (*f)(struct super_block *, void *),
@@ -1071,15 +1077,8 @@ static struct super_block *__cifs_get_super(void (*f)(struct super_block *, voidfor (; *fs_type; fs_type++) {iterate_supers_type (*fs_type, f, &sd); -if (sd.sb) { -/* -* Grab an active reference in order to prevent automounts (DFS links) -* of expiring and then freeing up our cifs superblock pointer while -* we're doing failover. -*/ -cifs_sb_active (sd.sb); +if (sd.sb)return sd.sb; - } }return ERR_PTR (-EINVAL ); }
Signature · 1 line
2.53.0