Re: [RFC PATCH v2 2/2] blk-mq: Lockout tagset iter when freeing rqs

From: Bart Van Assche
Date: Mon Dec 21 2020 - 13:10:52 EST


On 12/21/20 4:06 AM, John Garry wrote:
> On 18/12/2020 22:43, Bart Van Assche wrote:
>> Does this mean that we do not yet have
>> a full explanation about why the above call stack can be triggered?
>
> We understand it, and I'll describe my experiment in detail:
> a. fio runs on 2x disks, sda (root partition disk) and sdb.
> b. for sda, userpace triggers blk_mq_queue_tag_busy_iter(), as in
> stackframe above. Since its request queue is not frozen, it will iter
> the busy tags.
> c. on sdb, I continuously change the IO scheduler.
>
> So sdb request queue gets frozen as we switch IO sched, but we could
> have this sequence of events:
> - blk_mq_queue_tag_busy_iter() on sda takes reference to a sdb request
>    - Getting a tag and updating ->rqs[] in tagset is not atomic
> - requests for sdb cleared in tagset and request memory is freed
> - blk_mq_queue_tag_busy_iter() on sda still holds reference to sdb
> request and dereferences it -> UAF
>
> Hope it's clear. It is a bit unlikely, I will admit, but it still can
> happen and UAF is never good. So please let me know if other idea to solve.

Hi John,

Do you agree that all partitions (struct block_device) of a disk share a
request queue (block_device.bd_disk->queue)? I'm asking this because it
seems like in the above explanation it has been assumed that different
partitions use different request queues.

Thanks,

Bart.