From: l1za0.sec@gmail.com
To: axboe@kernel.dk
Cc: linux-block@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH] block: blk-mq: fix UAF in blk_mq_tagset_busy_iter
Date: Thu, 30 Apr 2026 12:28:21 +0800 [thread overview]
Message-ID: <20260430042821.29120-1-l1za0.sec@gmail.com> (raw)
From: Haocheng Yu <l1za0.sec@gmail.com>
A KASAN: slab-use-after-free Read in blk_mq_tagset_busy_iter is
reported by a modified Syzkaller-based kernel fuzzing tool we
developed.
This problem is caused by a race condition between
block/blk-mq-tag.c/blk_mq_tagset_busy_iter() and
block/blk-mq.c/blk_mq_realloc_tag_set_tags(). In
blk_mq_realloc_tag_set_tags(), set->tags is first freed, and then
new_tags is assigned to set->tags. However, this process is not
protected by synchronization. Therefore, if another process reads
tagset->tags in blk_mq_tagset_busy_iter() between these two steps,
it will cause a use-after-free read problem.
To fix this vulnerability, first save the old set->tags. After
updating set->tags to new_tags, wait for the reading side to exit
before releasing it. This avoids the problem of tagset->tags being
directly released while blk_mq_tagset_busy_iter() is still iterating.
Signed-off-by: Haocheng Yu <l1za0.sec@gmail.com>
---
The full reproducer is attached here:
# {Threaded:true Repeat:true RepeatTimes:0 Procs:8 Slowdown:1 Sandbox:none SandboxArg:0 Leak:false NetInjection:true NetDevices:true NetReset:true Cgroups:true BinfmtMisc:true CloseFDs:true KCSAN:false DevlinkPCI:false NicVF:false USB:true VhciInjection:true Wifi:true IEEE802154:true Sysctl:true Swap:true UseTmpDir:true HandleSegv:true Trace:false CallComments:true LegacyOptions:{Collide:false Fault:false FaultCall:0 FaultNth:0}}
r0 = syz_open_dev$ndb(&(0x7f0000000000), 0x0, 0xc0400)
r1 = syz_open_dev$ndb(&(0x7f0000000000), 0x0, 0x80040)
ioctl$NBD_SET_FLAGS(r1, 0xab0a, 0x9ad)
socketpair$nbd(0x1, 0x1, 0x0, &(0x7f0000000080)={<r2=>0xffffffffffffffff})
r3 = syz_open_dev$dri(&(0x7f0000000100), 0xfffffffffffffffc, 0xc8503)
r4 = syz_open_dev$ndb(&(0x7f0000000000), 0x0, 0xc0400)
socketpair$nbd(0x1, 0x1, 0x0, &(0x7f0000000080)={<r5=>0xffffffffffffffff})
ioctl$NBD_SET_SOCK(r4, 0xab00, r5)
r6 = syz_open_dev$ndb(&(0x7f0000000240), 0x0, 0x12100)
ioctl$NBD_DO_IT(r6, 0xab03)
close_range(r3, 0xffffffffffffffff, 0x0)
ioctl$NBD_SET_SIZE_BLOCKS(0xffffffffffffffff, 0xab07, 0x1)
ioctl$NBD_SET_SOCK(r0, 0xab00, r2)
r7 = syz_open_dev$loop(&(0x7f0000000040), 0x1, 0x200)
ioctl$BLKPG(r7, 0x1269, &(0x7f00000001c0)={0x1, 0x0, 0x98, &(0x7f00000000c0)={0x5, 0x2, 0x10}})
close(0x5)
r8 = syz_open_dev$ndb(&(0x7f0000000000), 0x0, 0x100)
r9 = syz_open_dev$ndb(&(0x7f0000000000), 0x0, 0xc0400)
socketpair$nbd(0x1, 0x1, 0x0, &(0x7f0000000080)={<r10=>0xffffffffffffffff})
ioctl$NBD_SET_SOCK(r9, 0xab00, r10)
close(0x5)
r11 = syz_open_dev$ndb(&(0x7f0000000000), 0x0, 0x100)
ioctl$NBD_DO_IT(r11, 0xab03)
r12 = syz_open_dev$ndb(&(0x7f0000000040), 0x0, 0x0)
ioctl$NBD_CLEAR_SOCK(r12, 0xab04)
ioctl$NBD_DO_IT(r8, 0xab03)
socket$inet6_tcp(0xa, 0x1, 0x0)
syz_open_dev$ndb(&(0x7f0000000000), 0x0, 0xc0400)
block/blk-mq.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/block/blk-mq.c b/block/blk-mq.c
index d626d32f6e57..4357625a512d 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -4738,6 +4738,7 @@ static int blk_mq_realloc_tag_set_tags(struct blk_mq_tag_set *set,
int new_nr_hw_queues)
{
struct blk_mq_tags **new_tags;
+ struct blk_mq_tags **old_tags;
int i;
if (set->nr_hw_queues >= new_nr_hw_queues)
@@ -4751,8 +4752,10 @@ static int blk_mq_realloc_tag_set_tags(struct blk_mq_tag_set *set,
if (set->tags)
memcpy(new_tags, set->tags, set->nr_hw_queues *
sizeof(*set->tags));
- kfree(set->tags);
+ old_tags = set->tags;
set->tags = new_tags;
+ synchronize_srcu(&set->tags_srcu);
+ kfree(old_tags);
for (i = set->nr_hw_queues; i < new_nr_hw_queues; i++) {
if (!__blk_mq_alloc_map_and_rqs(set, i)) {
base-commit: 7d0a66e4bb9081d75c82ec4957c50034cb0ea449
--
2.51.0
next reply other threads:[~2026-04-30 4:28 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-30 4:28 l1za0.sec [this message]
2026-04-30 16:11 ` [PATCH] block: blk-mq: fix UAF in blk_mq_tagset_busy_iter Bart Van Assche
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=20260430042821.29120-1-l1za0.sec@gmail.com \
--to=l1za0.sec@gmail.com \
--cc=axboe@kernel.dk \
--cc=linux-block@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox