From 4912dab88baa5f7034dc9e38807804d470ae5438 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Wed, 28 Oct 2026 10:41:42 -0600 Subject: [PATCH] rnbd-srv: fix use-after-free on two CLOSE messages process_msg_close() looks the sess_dev up with a kref, drops it right away, and only then takes the session mutex for the teardown. A session has several connections handled by different workers, so two CLOSE messages for the same ID both finish the lookup before either one tears the sess_dev down, and the second one works on freed memory. Any host that can open a device on the server can do that. Take the mutex first and look the ID up with xa_load() under it. The second CLOSE then finds nothing. Fixes: 2de6c8de192b ("block/rnbd: server: main functionality") Cc: "Md. Haris Iqbal" Cc: Jack Wang Signed-off-by: Chris Mason Link: https://patch.msgid.link/20261028164415.1262013-40-axboe@kernel.dk Signed-off-by: Jens Axboe --- drivers/block/rnbd/rnbd-srv.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/block/rnbd/rnbd-srv.c b/drivers/block/rnbd/rnbd-srv.c index 1e3de82fd70b..1cfa2c580759 100644 --- a/drivers/block/rnbd/rnbd-srv.c +++ b/drivers/block/rnbd/rnbd-srv.c @@ -360,14 +360,15 @@ static void process_msg_close(struct rnbd_srv_session *srv_sess, trace_process_msg_close(srv_sess, close_msg); - sess_dev = rnbd_get_sess_dev(le32_to_cpu(close_msg->device_id), - srv_sess); - if (IS_ERR(sess_dev)) - return; - - rnbd_put_sess_dev(sess_dev); + /* + * Each teardown of a sess_dev runs under srv_sess->lock and erases the + * ID, so an entry that is found under the lock is alive. + */ mutex_lock(&srv_sess->lock); - rnbd_srv_destroy_dev_session_sysfs(sess_dev); + sess_dev = xa_load(&srv_sess->index_idr, + le32_to_cpu(close_msg->device_id)); + if (sess_dev) + rnbd_srv_destroy_dev_session_sysfs(sess_dev); mutex_unlock(&srv_sess->lock); }