mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
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: 2de6c8de19 ("block/rnbd: server: main functionality")
Cc: "Md. Haris Iqbal" <haris.iqbal@ionos.com>
Cc: Jack Wang <jinpu.wang@ionos.com>
Signed-off-by: Chris Mason <mason@kernel.org>
Link: https://patch.msgid.link/20261028164415.1262013-40-axboe@kernel.dk
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
81941915d5
commit
4912dab88b
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user