[PATCH 2/2] smb: client: skip NULL channel in __cifs_put_smb_ses()
From: Joseph Qi
Date: Tue Nov 03 2026 - 04:21:44 EST
cifs_chan_skip_or_disable() clears a secondary channel's slot in the
session (ses->chans[chan_index].server = NULL) without lowering
chan_count when the server stops supporting multichannel. When the
session is later released, __cifs_put_smb_ses() walks every slot up to
chan_count and calls cifs_put_tcp_session() on it, which dereferences
the server pointer immediately, so a slot left NULL by the skip path
makes the release crash with a NULL pointer dereference.
Clearing a slot without lowering chan_count is older than
cifs_chan_skip_or_disable(): cifs_chan_update_iface() could already
do the same since b54034a73baf9 ("cifs: during reconnect, update
interface if necessary"), and the release loop has been unguarded
since then. 12d1e301bdfd1 ("cifs: do not let cifs_chan_update_iface
deallocate channels") later removed that trigger, but the crash is
reachable through it on older kernels.
cifs_decrease_secondary_channels() already guards the same put with
if (server). Add the same guard to the release loop so a skipped
channel slot is left alone.
Fixes: b54034a73baf9 ("cifs: during reconnect, update interface if necessary")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Joseph Qi <joseph.qi@xxxxxxxxxxxxxxxxx>
---
fs/smb/client/connect.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
index e68fffb2ab2ea..6497b0d54fea7 100644
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -2200,7 +2200,8 @@ void __cifs_put_smb_ses(struct cifs_ses *ses)
kref_put(&ses->chans[i].iface->refcount, release_iface);
ses->chans[i].iface = NULL;
}
- cifs_put_tcp_session(ses->chans[i].server, 0);
+ if (ses->chans[i].server)
+ cifs_put_tcp_session(ses->chans[i].server, 0);
ses->chans[i].server = NULL;
}
--
2.39.3