FAILED: Patch "ksmbd: add chann_lock to protect ksmbd_chann_list xarray" failed to apply to 6.6-stable tree
Subsystems (3)
Sasha Levin
maintainerThe patch below does not apply to the 6.6-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,
Sasha
------------------ original commit in Linus's tree ------------------
From 4f3a06cc57976cafa8c6f716646be6c79a99e485 Mon Sep 17 00:00:00 2001
From: Namjae Jeon <[email protected]>
Date: Mon, 9 Feb 2026 10:43:19 +0900
Subject: [PATCH] ksmbd: add chann_lock to protect ksmbd_chann_list xarray
ksmbd_chann_list xarray lacks synchronization, allowing use-after-free in multi-channel sessions (between lookup_chann_list() and ksmbd_chann_del).
Adds rw_semaphore chann_lock to struct ksmbd_session and protects all xa_load/xa_store/xa_erase accesses.
--- fs/smb/server/mgmt/user_session.c | 5 +++++ fs/smb/server/mgmt/user_session.h | 1 + fs/smb/server/smb2pdu.c | 12 +++++++++++- 3 files changed, 17 insertions(+), 1 deletion(-)
fs/smb/server/mgmt/user_session.c +5 -0
@@ -244,12 +244,14 @@ static void free_channel_list(struct ksmbd_session *sess)struct channel *chann;unsigned long index; +down_write (&sess->chann_lock);xa_for_each (&sess->ksmbd_chann_list, index, chann) {xa_erase (&sess->ksmbd_chann_list, index);kfree (chann); }xa_destroy (&sess->ksmbd_chann_list); +up_write (&sess->chann_lock); } static void __session_rpc_close(struct ksmbd_session *sess,
@@ -434,7 +436,9 @@ static int ksmbd_chann_del(struct ksmbd_conn *conn, struct ksmbd_session *sess) {struct channel *chann; +down_write (&sess->chann_lock); chann =xa_erase (&sess->ksmbd_chann_list, (long )conn); +up_write (&sess->chann_lock);if (!chann)return -ENOENT ;
@@ -668,6 +672,7 @@ static struct ksmbd_session *__session_create(int protocol)rwlock_init (&sess->tree_conns_lock);atomic_set (&sess->refcnt,2 );init_rwsem (&sess->rpc_lock); +init_rwsem (&sess->chann_lock); ret =__init_smb2_session (sess);if (ret)
fs/smb/server/mgmt/user_session.h +1 -0
@@ -48,6 +48,7 @@ struct ksmbd_session {char sess_key[CIFS_KEY_SIZE ];struct hlist_node hlist; +struct rw_semaphore chann_lock;struct xarray ksmbd_chann_list;struct xarray tree_conns;struct ida tree_conn_ida;
fs/smb/server/smb2pdu.c +11 -1
@@ -80,7 +80,13 @@ static inline bool check_session_id(struct ksmbd_conn *conn, u64 id)struct channel *lookup_chann_list (struct ksmbd_session *sess,struct ksmbd_conn *conn) { -return xa_load (&sess->ksmbd_chann_list, (long )conn); +struct channel *chann; + +down_read (&sess->chann_lock); + chann =xa_load (&sess->ksmbd_chann_list, (long )conn); +up_read (&sess->chann_lock); + +return chann; }/**
@@ -1559,8 +1565,10 @@ static int ntlm_authenticate(struct ksmbd_work *work,return -ENOMEM ; chann->conn = conn; +down_write (&sess->chann_lock); old =xa_store (&sess->ksmbd_chann_list, (long )conn, chann,KSMBD_DEFAULT_GFP ); +up_write (&sess->chann_lock);if (xa_is_err (old)) {kfree (chann);return xa_err (old);
@@ -1652,8 +1660,10 @@ static int krb5_authenticate(struct ksmbd_work *work,return -ENOMEM ; chann->conn = conn; +down_write (&sess->chann_lock); old =xa_store (&sess->ksmbd_chann_list, (long )conn, chann,KSMBD_DEFAULT_GFP ); +up_write (&sess->chann_lock);if (xa_is_err (old)) {kfree (chann);return xa_err (old);
Signature · 1 line
2.51.0