Thread (9 messages) 9 messages, 5 authors, 2021-03-26

Re: [PATCH] blk-mq: Fix races between iterating over requests and freeing requests

From: Shinichiro Kawasaki <hidden>
Date: 2021-03-22 00:43:38

On Mar 18, 2021 / 18:00, Bart Van Assche wrote:
Multiple users have reported use-after-free complaints similar to the
following (see also https://lore.kernel.org/linux-block/1545261885.185366.488.camel@acm.org/ (local)):

BUG: KASAN: use-after-free in bt_iter+0x86/0xf0
Read of size 8 at addr ffff88803b335240 by task fio/21412

CPU: 0 PID: 21412 Comm: fio Tainted: G        W         4.20.0-rc6-dbg+ #3
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014
Call Trace:
 dump_stack+0x86/0xca
 print_address_description+0x71/0x239
 kasan_report.cold.5+0x242/0x301
 __asan_load8+0x54/0x90
 bt_iter+0x86/0xf0
 blk_mq_queue_tag_busy_iter+0x373/0x5e0
 blk_mq_in_flight+0x96/0xb0
 part_in_flight+0x40/0x140
 part_round_stats+0x18e/0x370
 blk_account_io_start+0x3d7/0x670
 blk_mq_bio_to_request+0x19c/0x3a0
 blk_mq_make_request+0x7a9/0xcb0
 generic_make_request+0x41d/0x960
 submit_bio+0x9b/0x250
 do_blockdev_direct_IO+0x435c/0x4c70
 __blockdev_direct_IO+0x79/0x88
 ext4_direct_IO+0x46c/0xc00
 generic_file_direct_write+0x119/0x210
 __generic_file_write_iter+0x11c/0x280
 ext4_file_write_iter+0x1b8/0x6f0
 aio_write+0x204/0x310
 io_submit_one+0x9d3/0xe80
 __x64_sys_io_submit+0x115/0x340
 do_syscall_64+0x71/0x210

When multiple request queues share a tag set and when switching the I/O
scheduler for one of the request queues that uses this tag set, the
following race can happen:
* blk_mq_tagset_busy_iter() calls bt_tags_iter() and bt_tags_iter() assigns
  a pointer to a scheduler request to the local variable 'rq'.
* blk_mq_sched_free_requests() is called to free hctx->sched_tags.
* blk_mq_tagset_busy_iter() dereferences 'rq' and triggers a use-after-free.

Fix this race as follows:
* Use rcu_assign_pointer() and srcu_dereference() to access hctx->tags->rqs[].
* Protect hctx->tags->rqs[] reads with an SRCU read-side lock.
* Call srcu_barrier() before freeing scheduler requests.

Cc: Christoph Hellwig <hch@lst.de>
Cc: Ming Lei <redacted>
Cc: John Garry <redacted>
Cc: Khazhy Kumykov <redacted>
Cc: Shinichiro Kawasaki <redacted>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
I confirmed that this patch avoids the KASAN use-after-free message observed
during blktests block/005 run on HDDs behind SAS-HBA. Looks good from testing
point of view.

Tested-by: Shin'ichiro Kawasaki <redacted>

-- 
Best Regards,
Shin'ichiro Kawasaki
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help