From: Kai Aizen <kai.aizen.dev@gmail.com>
To: stable@vger.kernel.org
Cc: gregkh@linuxfoundation.org, linkinjeon@kernel.org,
linux-cifs@vger.kernel.org, samba-technical@lists.samba.org
Subject: [PATCH 6.6.y] ksmbd: add chann_lock to protect ksmbd_chann_list xarray
Date: Sat, 2 May 2026 01:51:50 +0300 [thread overview]
Message-ID: <20260501225152.90136-1-kai.aizen.dev@gmail.com> (raw)
From: Namjae Jeon <linkinjeon@kernel.org>
[ Upstream commit 4f3a06cc57976cafa8c6f716646be6c79a99e485 ]
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.
Backport notes for linux-6.6.y:
- File paths and surrounding context are identical to mainline at the
time of the fix. The xa_store call sites in
ntlm_authenticate / krb5_authenticate use the older form
`xa_store(..., GFP_KERNEL)` rather than the newer
`old = xa_store(..., KSMBD_DEFAULT_GFP)`; the lock-wrap is
structurally identical.
CVE: CVE-2026-23226
Cc: stable@vger.kernel.org # 6.6.y
Reported-by: Igor Stepansky <igor.stepansky@orca.security>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
[backport for linux-6.6.y, verified 2026-05-01]
---
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(-)
diff --git a/fs/smb/server/mgmt/user_session.c b/fs/smb/server/mgmt/user_session.c
--- a/fs/smb/server/mgmt/user_session.c
+++ b/fs/smb/server/mgmt/user_session.c
@@ -30,12 +30,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,
@@ -218,7 +220,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;
@@ -451,6 +455,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)
diff --git a/fs/smb/server/mgmt/user_session.h b/fs/smb/server/mgmt/user_session.h
--- a/fs/smb/server/mgmt/user_session.h
+++ b/fs/smb/server/mgmt/user_session.h
@@ -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;
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -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,7 +1565,9 @@ static int ntlm_authenticate(struct ksmbd_work *work,
return -ENOMEM;
chann->conn = conn;
+ down_write(&sess->chann_lock);
xa_store(&sess->ksmbd_chann_list, (long)conn, chann, GFP_KERNEL);
+ up_write(&sess->chann_lock);
}
}
@@ -1652,7 +1660,9 @@ static int krb5_authenticate(struct ksmbd_work *work,
return -ENOMEM;
chann->conn = conn;
+ down_write(&sess->chann_lock);
xa_store(&sess->ksmbd_chann_list, (long)conn, chann, GFP_KERNEL);
+ up_write(&sess->chann_lock);
}
}
--
2.43.0
next reply other threads:[~2026-05-01 22:51 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-01 22:51 Kai Aizen [this message]
2026-05-01 22:51 ` [PATCH 6.1.y] ksmbd: add chann_lock to protect ksmbd_chann_list xarray Kai Aizen
2026-05-01 22:51 ` [PATCH 5.15.y] " Kai Aizen
2026-05-03 18:17 ` [PATCH 6.6.y] " Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260501225152.90136-1-kai.aizen.dev@gmail.com \
--to=kai.aizen.dev@gmail.com \
--cc=gregkh@linuxfoundation.org \
--cc=linkinjeon@kernel.org \
--cc=linux-cifs@vger.kernel.org \
--cc=samba-technical@lists.samba.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.