From: Ming Lei <ming.lei@redhat.com>
To: Fengnan Chang <fengnanchang@gmail.com>
Cc: axboe@kernel.dk, linux-block@vger.kernel.org, hare@suse.de,
hch@lst.de, yukuai3@huawei.com,
Fengnan Chang <changfengnan@bytedance.com>
Subject: Re: [PATCH v2 2/2] blk-mq: fix potential uaf for 'queue_hw_ctx'
Date: Thu, 27 Nov 2025 11:33:22 +0800 [thread overview]
Message-ID: <aSfGggOS8o_nOQPI@fedora> (raw)
In-Reply-To: <20251127013908.66118-3-fengnanchang@gmail.com>
On Thu, Nov 27, 2025 at 09:39:08AM +0800, Fengnan Chang wrote:
> From: Fengnan Chang <changfengnan@bytedance.com>
>
> This is just apply Kuai's patch in [1] with mirror changes.
>
> blk_mq_realloc_hw_ctxs() will free the 'queue_hw_ctx'(e.g. undate
> submit_queues through configfs for null_blk), while it might still be
> used from other context(e.g. switch elevator to none):
>
> t1 t2
> elevator_switch
> blk_mq_unquiesce_queue
> blk_mq_run_hw_queues
> queue_for_each_hw_ctx
> // assembly code for hctx = (q)->queue_hw_ctx[i]
> mov 0x48(%rbp),%rdx -> read old queue_hw_ctx
>
> __blk_mq_update_nr_hw_queues
> blk_mq_realloc_hw_ctxs
> hctxs = q->queue_hw_ctx
> q->queue_hw_ctx = new_hctxs
> kfree(hctxs)
> movslq %ebx,%rax
> mov (%rdx,%rax,8),%rdi ->uaf
>
> This problem was found by code review, and I comfirmed that the concurrent
> scenario do exist(specifically 'q->queue_hw_ctx' can be changed during
> blk_mq_run_hw_queues()), however, the uaf problem hasn't been repoduced yet
> without hacking the kernel.
>
> Sicne the queue is freezed in __blk_mq_update_nr_hw_queues(), fix the
> problem by protecting 'queue_hw_ctx' through rcu where it can be accessed
> without grabbing 'q_usage_counter'.
>
> [1] https://lore.kernel.org/all/20220225072053.2472431-1-yukuai3@huawei.com/
>
> Signed-off-by: Yu Kuai <yukuai3@huawei.com>
> Signed-off-by: Fengnan Chang <changfengnan@bytedance.com>
> ---
> block/blk-mq.c | 7 ++++++-
> block/blk-mq.h | 11 +++++++++++
> include/linux/blk-mq.h | 2 +-
> include/linux/blkdev.h | 2 +-
> 4 files changed, 19 insertions(+), 3 deletions(-)
>
> diff --git a/block/blk-mq.c b/block/blk-mq.c
> index eed12fab3484..0b8b72194003 100644
> --- a/block/blk-mq.c
> +++ b/block/blk-mq.c
> @@ -4524,7 +4524,12 @@ static void __blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set,
> if (hctxs)
> memcpy(new_hctxs, hctxs, q->nr_hw_queues *
> sizeof(*hctxs));
> - q->queue_hw_ctx = new_hctxs;
> + rcu_assign_pointer(q->queue_hw_ctx, new_hctxs);
> + /*
> + * Make sure reading the old queue_hw_ctx from other
> + * context concurrently won't trigger uaf.
> + */
> + synchronize_rcu_expedited();
> kfree(hctxs);
> hctxs = new_hctxs;
> }
> diff --git a/block/blk-mq.h b/block/blk-mq.h
> index 80a3f0c2bce7..52852fab78f0 100644
> --- a/block/blk-mq.h
> +++ b/block/blk-mq.h
> @@ -87,6 +87,17 @@ static inline struct blk_mq_hw_ctx *blk_mq_map_queue_type(struct request_queue *
> return q->queue_hw_ctx[q->tag_set->map[type].mq_map[cpu]];
> }
>
> +static inline struct blk_mq_hw_ctx *queue_hctx(struct request_queue *q, int id)
> +{
> + struct blk_mq_hw_ctx *hctx;
> +
> + rcu_read_lock();
> + hctx = rcu_dereference(q->queue_hw_ctx)[id];
> + rcu_read_unlock();
> +
> + return hctx;
> +}
If `hctx` is retrieved from old table, uaf will be triggered on
`hctx` dereference after returning from queue_hctx().
So rcu read lock should be held anywhere for `hctx` deference.
Thanks,
Ming
next prev parent reply other threads:[~2025-11-27 3:33 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-27 1:39 [PATCH v2 0/2] blk-mq: use array manage hctx map instead of xarray Fengnan Chang
2025-11-27 1:39 ` [PATCH v2 1/2] " Fengnan Chang
2025-11-27 1:39 ` [PATCH v2 2/2] blk-mq: fix potential uaf for 'queue_hw_ctx' Fengnan Chang
2025-11-27 3:33 ` Ming Lei [this message]
2025-11-27 3:38 ` Ming Lei
2025-11-27 18:46 ` kernel test robot
2025-11-27 20:30 ` kernel test robot
2025-11-27 20:41 ` kernel test robot
2025-11-27 23:32 ` kernel test robot
2025-11-27 2:47 ` [PATCH v2 0/2] blk-mq: use array manage hctx map instead of xarray Jens Axboe
2025-11-27 2:55 ` fengnan chang
2025-11-27 2:49 ` Jens Axboe
2025-11-27 3:00 ` fengnan chang
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=aSfGggOS8o_nOQPI@fedora \
--to=ming.lei@redhat.com \
--cc=axboe@kernel.dk \
--cc=changfengnan@bytedance.com \
--cc=fengnanchang@gmail.com \
--cc=hare@suse.de \
--cc=hch@lst.de \
--cc=linux-block@vger.kernel.org \
--cc=yukuai3@huawei.com \
/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.