* [syzbot] [block?] general protection fault in lo_rw_aio
@ 2026-04-18 0:02 syzbot
2026-04-21 11:05 ` Tetsuo Handa
0 siblings, 1 reply; 6+ messages in thread
From: syzbot @ 2026-04-18 0:02 UTC (permalink / raw)
To: axboe, linux-block, linux-kernel, syzkaller-bugs
Hello,
syzbot found the following issue on:
HEAD commit: 43cfbdda5af6 Merge tag 'for-linus-iommufd' of git://git.ke..
git tree: upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=101e4702580000
kernel config: https://syzkaller.appspot.com/x/.config?x=4660d1ff2985517b
dashboard link: https://syzkaller.appspot.com/bug?extid=cd8a9a308e879a4e2c28
compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
Unfortunately, I don't have any reproducer for this issue yet.
Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/0867fa0b89e8/disk-43cfbdda.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/754859270006/vmlinux-43cfbdda.xz
kernel image: https://storage.googleapis.com/syzbot-assets/cd6cca8d06c9/bzImage-43cfbdda.xz
IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+cd8a9a308e879a4e2c28@syzkaller.appspotmail.com
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000014: 0000 [#1] SMP KASAN PTI
KASAN: null-ptr-deref in range [0x00000000000000a0-0x00000000000000a7]
CPU: 1 UID: 0 PID: 1174 Comm: kworker/u8:8 Not tainted syzkaller #0 PREEMPT_{RT,(full)}
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 03/18/2026
Workqueue: loop2 loop_workfn
RIP: 0010:file_inode include/linux/fs.h:1353 [inline]
RIP: 0010:kiocb_start_write include/linux/fs.h:2763 [inline]
RIP: 0010:lo_rw_aio+0xaa9/0xf00 drivers/block/loop.c:401
Code: 89 33 31 ff 8b 5c 24 44 89 de e8 32 2b 3f fc 85 db 0f 84 ca 00 00 00 48 8b 44 24 58 48 8d 98 a0 00 00 00 48 89 d8 48 c1 e8 03 <42> 80 3c 28 00 74 08 48 89 df e8 e8 ae a5 fc 4c 89 7c 24 10 48 8b
RSP: 0018:ffffc9000655f620 EFLAGS: 00010206
RAX: 0000000000000014 RBX: 00000000000000a0 RCX: ffff888029649ec0
RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000000
RBP: ffffc9000655f790 R08: 0000000000000000 R09: 0000000000000000
R10: ffffc9000655f6e3 R11: fffff52000cabede R12: ffff888026c9b090
R13: dffffc0000000000 R14: 0000000000000000 R15: ffff888026c9b0b0
FS: 0000000000000000(0000) GS:ffff88812620f000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000555591947a68 CR3: 000000005515a000 CR4: 00000000003526f0
Call Trace:
<TASK>
do_req_filebacked drivers/block/loop.c:433 [inline]
loop_handle_cmd drivers/block/loop.c:1925 [inline]
loop_process_work+0x637/0x11b0 drivers/block/loop.c:1960
process_one_work kernel/workqueue.c:3302 [inline]
process_scheduled_works+0xb5d/0x1860 kernel/workqueue.c:3385
worker_thread+0xa53/0xfc0 kernel/workqueue.c:3466
kthread+0x388/0x470 kernel/kthread.c:436
ret_from_fork+0x514/0xb70 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
</TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:file_inode include/linux/fs.h:1353 [inline]
RIP: 0010:kiocb_start_write include/linux/fs.h:2763 [inline]
RIP: 0010:lo_rw_aio+0xaa9/0xf00 drivers/block/loop.c:401
Code: 89 33 31 ff 8b 5c 24 44 89 de e8 32 2b 3f fc 85 db 0f 84 ca 00 00 00 48 8b 44 24 58 48 8d 98 a0 00 00 00 48 89 d8 48 c1 e8 03 <42> 80 3c 28 00 74 08 48 89 df e8 e8 ae a5 fc 4c 89 7c 24 10 48 8b
RSP: 0018:ffffc9000655f620 EFLAGS: 00010206
RAX: 0000000000000014 RBX: 00000000000000a0 RCX: ffff888029649ec0
RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000000
RBP: ffffc9000655f790 R08: 0000000000000000 R09: 0000000000000000
R10: ffffc9000655f6e3 R11: fffff52000cabede R12: ffff888026c9b090
R13: dffffc0000000000 R14: 0000000000000000 R15: ffff888026c9b0b0
FS: 0000000000000000(0000) GS:ffff88812620f000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000555591947a68 CR3: 000000005515a000 CR4: 00000000003526f0
----------------
Code disassembly (best guess):
0: 89 33 mov %esi,(%rbx)
2: 31 ff xor %edi,%edi
4: 8b 5c 24 44 mov 0x44(%rsp),%ebx
8: 89 de mov %ebx,%esi
a: e8 32 2b 3f fc call 0xfc3f2b41
f: 85 db test %ebx,%ebx
11: 0f 84 ca 00 00 00 je 0xe1
17: 48 8b 44 24 58 mov 0x58(%rsp),%rax
1c: 48 8d 98 a0 00 00 00 lea 0xa0(%rax),%rbx
23: 48 89 d8 mov %rbx,%rax
26: 48 c1 e8 03 shr $0x3,%rax
* 2a: 42 80 3c 28 00 cmpb $0x0,(%rax,%r13,1) <-- trapping instruction
2f: 74 08 je 0x39
31: 48 89 df mov %rbx,%rdi
34: e8 e8 ae a5 fc call 0xfca5af21
39: 4c 89 7c 24 10 mov %r15,0x10(%rsp)
3e: 48 rex.W
3f: 8b .byte 0x8b
---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.
syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.
If the report is already addressed, let syzbot know by replying with:
#syz fix: exact-commit-title
If you want to overwrite report's subsystems, reply with:
#syz set subsystems: new-subsystem
(See the list of subsystem names on the web dashboard)
If the report is a duplicate of another one, reply with:
#syz dup: exact-subject-of-another-report
If you want to undo deduplication, reply with:
#syz undup
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [syzbot] [block?] general protection fault in lo_rw_aio
2026-04-18 0:02 [syzbot] [block?] general protection fault in lo_rw_aio syzbot
@ 2026-04-21 11:05 ` Tetsuo Handa
2026-05-11 11:43 ` [PATCH] loop: Fix NULL pointer dereference by synchronizing lo_release and loop_queue_rq Tetsuo Handa
0 siblings, 1 reply; 6+ messages in thread
From: Tetsuo Handa @ 2026-04-21 11:05 UTC (permalink / raw)
To: syzbot, axboe, linux-block, syzkaller-bugs
I confirmed that this NULL pointer dereference is triggered by
__loop_clr_fd() clearing lo->lo_backing_file before aio request
is processed. A debug printk() patch at
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/drivers/block/loop.c?h=next-20260420&id=7454b88731fd320e7dbfbf1ea72f25705c3befc0
generated the following output.
file == NULL
Last __loop_clr_fd() call was 5 jiffies ago by udevd (16676)
lo_release+0x35b/0x9d0
blkdev_release+0x15/0x20 block/fops.c:705
__fput+0x461/0xa70 fs/file_table.c:510
fput_close_sync+0x11f/0x240 fs/file_table.c:615
__do_sys_close fs/open.c:1507 [inline]
__se_sys_close fs/open.c:1492 [inline]
__x64_sys_close+0x7e/0x110 fs/open.c:1492
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x15f/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000014: 0000 [#1] SMP KASAN PTI
KASAN: null-ptr-deref in range [0x00000000000000a0-0x00000000000000a7]
CPU: 0 UID: 0 PID: 180 Comm: kworker/u8:6 Tainted: G L syzkaller #0 PREEMPT_{RT,(full)}
Tainted: [L]=SOFTLOCKUP
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 03/18/2026
Workqueue: loop4 loop_workfn
RIP: 0010:file_inode include/linux/fs.h:1353 [inline]
RIP: 0010:kiocb_start_write include/linux/fs.h:2756 [inline]
RIP: 0010:lo_rw_aio+0xb88/0x1190 drivers/block/loop.c:429
Code: 1e d8 34 fc 45 85 e4 0f 84 d8 00 00 00 48 8b 44 24 58 48 8d 98 a0 00 00 00 48 89 d8 48 c1 e8 03 48 b9 00 00 00 00 00 fc ff df <80> 3c 08 00 74 08 48 89 df e8 8a 4c 9e fc 48 8b 1b 48 83 c3 28 49
RSP: 0018:ffffc90003907660 EFLAGS: 00010206
RAX: 0000000000000014 RBX: 00000000000000a0 RCX: dffffc0000000000
RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000000
RBP: ffffc900039077d0 R08: 0000000000000000 R09: 0000000000000000
R10: ffffc90003907723 R11: fffff52000720ee6 R12: 0000000000000001
R13: ffff888026ca2c90 R14: 0000000000000000 R15: dffffc0000000000
FS: 0000000000000000(0000) GS:ffff888125eb7000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 000055555b199a28 CR3: 000000003a2c0000 CR4: 00000000003526f0
Call Trace:
<TASK>
do_req_filebacked drivers/block/loop.c:461 [inline]
loop_handle_cmd drivers/block/loop.c:1960 [inline]
loop_process_work+0x647/0x1560 drivers/block/loop.c:1995
process_one_work+0x9a3/0x1710 kernel/workqueue.c:3312
process_scheduled_works kernel/workqueue.c:3403 [inline]
worker_thread+0xba8/0x11e0 kernel/workqueue.c:3489
kthread+0x388/0x470 kernel/kthread.c:436
ret_from_fork+0x514/0xb70 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
</TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:file_inode include/linux/fs.h:1353 [inline]
RIP: 0010:kiocb_start_write include/linux/fs.h:2756 [inline]
RIP: 0010:lo_rw_aio+0xb88/0x1190 drivers/block/loop.c:429
Code: 1e d8 34 fc 45 85 e4 0f 84 d8 00 00 00 48 8b 44 24 58 48 8d 98 a0 00 00 00 48 89 d8 48 c1 e8 03 48 b9 00 00 00 00 00 fc ff df <80> 3c 08 00 74 08 48 89 df e8 8a 4c 9e fc 48 8b 1b 48 83 c3 28 49
RSP: 0018:ffffc90003907660 EFLAGS: 00010206
RAX: 0000000000000014 RBX: 00000000000000a0 RCX: dffffc0000000000
RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000000
RBP: ffffc900039077d0 R08: 0000000000000000 R09: 0000000000000000
R10: ffffc90003907723 R11: fffff52000720ee6 R12: 0000000000000001
R13: ffff888026ca2c90 R14: 0000000000000000 R15: dffffc0000000000
FS: 0000000000000000(0000) GS:ffff888125eb7000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 000055555b199a28 CR3: 000000003a2c0000 CR4: 00000000003526f0
Either fput() is called without corresponding fget(), or some recent changes
has changed timing of start processing aio request?
Since this problem started after the merge window opened, the culprit commit
might be in between commit a028739a4330 ("Merge tag 'block-7.0-20260305' of
git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux") and
commit 7fe6ac157b7e ("Merge tag 'for-7.1/block-20260411' of
git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux").
Also, syzbot was not testing changes in linux-next since next-20260403,
and found this problem in next-20260413.
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH] loop: Fix NULL pointer dereference by synchronizing lo_release and loop_queue_rq
2026-04-21 11:05 ` Tetsuo Handa
@ 2026-05-11 11:43 ` Tetsuo Handa
2026-05-11 15:58 ` Bart Van Assche
0 siblings, 1 reply; 6+ messages in thread
From: Tetsuo Handa @ 2026-05-11 11:43 UTC (permalink / raw)
To: Jens Axboe, linux-block, LKML, Christoph Hellwig, Bart Van Assche,
Damien Le Moal
Summary:
This patch addresses a NULL pointer dereference in lo_rw_aio() by
introducing SRCU-based synchronization and explicit workqueue draining
during device release. This race appears to have been exacerbated or
introduced by recent changes in the block layer's request completion and
freezing logic.
Problem Description:
A NULL pointer dereference was reported by syzbot. The crash occurs when
lo_rw_aio() access lo->lo_backing_file which has already been cleared by
__loop_clr_fd().
The investigation suggests a gap between loop_queue_rq() and the driver's
internal workqueue. Even when the block layer attempts to freeze the queue,
requests that have already passed the loop_queue_rq() state check but have
not yet been queued to lo->workqueue can "leak" and execute after
lo_release() has proceeded to teardown the device.
Suspicious Commits and Behavioral Changes:
We suspect this race became visible due to behavioral changes in how the
block layer handles request completion and synchronization, specifically:
1. Commit 65565ca5f99b ("block: unify the synchronous bi_end_io
callbacks"): This unified completion path might have altered the timing
or the visibility of in-flight requests during a queue freeze, allowing
lo_release() to proceed before the loop driver's internal asynchronous
work has been fully accounted for.
2. Changes in blk_mq_freeze_queue(): In older kernels, the freeze mechanism
might have more effectively covered the window between queue_rq and the
driver's execution of that request. The current behavior seems to allow
__loop_clr_fd() to run while loop_queue_rq() is still in the middle of
scheduling work.
Stability and Backporting:
Because the underlying cause is tied to recent block layer refactoring,
this patch should not be backported to older stable kernels without careful
verification, as it may be unnecessary or lead to performance regressions
due to the added SRCU overhead.
Solution:
The patch closes the race window using SRCU:
* loop_queue_rq: Wrapped in srcu_read_lock() to ensure that once a request
passes the Lo_bound check, the corresponding queue_work() must complete
before the teardown path can finish its synchronization.
* lo_release: Calls synchronize_srcu() followed by drain_workqueue(). This
sequence ensures:
* No new work can be scheduled (lo_state change).
* All ongoing scheduling calls have finished (synchronize_srcu).
* All scheduled work has finished executing (drain_workqueue).
* Finally, it is safe to clear lo_backing_file.
Trace Evidence:
Console logs with debug printk() patch confirm that __loop_clr_fd() has
cleared the file for loop3 between multiple lo_rw_aio() requests.
[ 122.956248][ T6148] loop3: detected capacity change from 0 to 32768
[ 122.958217][ T6142] lo_rw_aio(loop3) starting read with raw_refcnt=0x0, refcnt=1
(...snipped...)
[ 123.234786][ T44] lo_rw_aio(loop3) starting read with raw_refcnt=0x0, refcnt=1
[ 123.254716][ T6148] __loop_clr_fd(loop3) clearing lo_backing_file with raw_refcnt=0x0, refcnt=1
[ 123.265134][ T180] lo_rw_aio(loop3) starting write with NULL file (already cleared?)
[ 123.265221][ T180] Oops: general protection fault, probably for non-canonical address 0xdffffc0000000014: 0000 [#1] SMP KASAN PTI
[ 123.265238][ T180] KASAN: null-ptr-deref in range [0x00000000000000a0-0x00000000000000a7]
[ 123.265255][ T180] CPU: 0 UID: 0 PID: 180 Comm: kworker/u8:7 Not tainted syzkaller #0 PREEMPT_{RT,(full)}
[ 123.265276][ T180] Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/18/2026
[ 123.265287][ T180] Workqueue: loop3 loop_workfn
[ 123.265320][ T180] RIP: 0010:lo_rw_aio+0xd1d/0x1170
Reported-by: syzbot+cd8a9a308e879a4e2c28@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=cd8a9a308e879a4e2c28
Analyzed-by: AI Mode in Google Search (no mail address)
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
Since this race condition is difficult to reproduce, we can't do bisection.
I hope you can figure out what has changed in the block layer for this merge window.
You might want to revert instead of modifying the loop driver.
drivers/block/loop.c | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 0000913f7efc..9be47ce97dab 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -93,6 +93,7 @@ struct loop_cmd {
static DEFINE_IDR(loop_index_idr);
static DEFINE_MUTEX(loop_ctl_mutex);
static DEFINE_MUTEX(loop_validate_mutex);
+DEFINE_SRCU(loop_io_srcu);
/**
* loop_global_lock_killable() - take locks for safe loop_validate_file() test
@@ -1747,8 +1748,19 @@ static void lo_release(struct gendisk *disk)
need_clear = (lo->lo_state == Lo_rundown);
mutex_unlock(&lo->lo_mutex);
- if (need_clear)
+ if (need_clear) {
+ /*
+ * Now that loop_queue_rq() sees lo->lo_state != Lo_bound,
+ * wait for already started loop_queue_rq() to complete.
+ */
+ synchronize_srcu(&loop_io_srcu);
+ /*
+ * Now that no more works are scheduled by loop_queue_rq(),
+ * wait for already scheduled works to complete.
+ */
+ drain_workqueue(lo->workqueue);
__loop_clr_fd(lo);
+ }
}
static void lo_free_disk(struct gendisk *disk)
@@ -1854,11 +1866,15 @@ static blk_status_t loop_queue_rq(struct blk_mq_hw_ctx *hctx,
struct request *rq = bd->rq;
struct loop_cmd *cmd = blk_mq_rq_to_pdu(rq);
struct loop_device *lo = rq->q->queuedata;
+ int idx;
blk_mq_start_request(rq);
- if (data_race(READ_ONCE(lo->lo_state)) != Lo_bound)
+ idx = srcu_read_lock(&loop_io_srcu);
+ if (data_race(READ_ONCE(lo->lo_state)) != Lo_bound) {
+ srcu_read_unlock(&loop_io_srcu, idx);
return BLK_STS_IOERR;
+ }
switch (req_op(rq)) {
case REQ_OP_FLUSH:
@@ -1888,6 +1904,7 @@ static blk_status_t loop_queue_rq(struct blk_mq_hw_ctx *hctx,
#endif
loop_queue_work(lo, cmd);
+ srcu_read_unlock(&loop_io_srcu, idx);
return BLK_STS_OK;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] loop: Fix NULL pointer dereference by synchronizing lo_release and loop_queue_rq
2026-05-11 11:43 ` [PATCH] loop: Fix NULL pointer dereference by synchronizing lo_release and loop_queue_rq Tetsuo Handa
@ 2026-05-11 15:58 ` Bart Van Assche
2026-05-11 17:43 ` Tetsuo Handa
0 siblings, 1 reply; 6+ messages in thread
From: Bart Van Assche @ 2026-05-11 15:58 UTC (permalink / raw)
To: Tetsuo Handa, Jens Axboe, linux-block, LKML, Christoph Hellwig,
Damien Le Moal
On 5/11/26 4:43 AM, Tetsuo Handa wrote:
> diff --git a/drivers/block/loop.c b/drivers/block/loop.c
> index 0000913f7efc..9be47ce97dab 100644
> --- a/drivers/block/loop.c
> +++ b/drivers/block/loop.c
> @@ -93,6 +93,7 @@ struct loop_cmd {
> static DEFINE_IDR(loop_index_idr);
> static DEFINE_MUTEX(loop_ctl_mutex);
> static DEFINE_MUTEX(loop_validate_mutex);
> +DEFINE_SRCU(loop_io_srcu);
>
> /**
> * loop_global_lock_killable() - take locks for safe loop_validate_file() test
> @@ -1747,8 +1748,19 @@ static void lo_release(struct gendisk *disk)
> need_clear = (lo->lo_state == Lo_rundown);
> mutex_unlock(&lo->lo_mutex);
>
> - if (need_clear)
> + if (need_clear) {
> + /*
> + * Now that loop_queue_rq() sees lo->lo_state != Lo_bound,
> + * wait for already started loop_queue_rq() to complete.
> + */
> + synchronize_srcu(&loop_io_srcu);
> + /*
> + * Now that no more works are scheduled by loop_queue_rq(),
> + * wait for already scheduled works to complete.
> + */
> + drain_workqueue(lo->workqueue);
> __loop_clr_fd(lo);
> + }
> }
There is already a mechanism in the block layer to wait for pending
.queue_rq() calls to complete. Please take a look at
blk_mq_quiesce_queue().
> static void lo_free_disk(struct gendisk *disk)
> @@ -1854,11 +1866,15 @@ static blk_status_t loop_queue_rq(struct blk_mq_hw_ctx *hctx,
> struct request *rq = bd->rq;
> struct loop_cmd *cmd = blk_mq_rq_to_pdu(rq);
> struct loop_device *lo = rq->q->queuedata;
> + int idx;
>
> blk_mq_start_request(rq);
>
> - if (data_race(READ_ONCE(lo->lo_state)) != Lo_bound)
> + idx = srcu_read_lock(&loop_io_srcu);
> + if (data_race(READ_ONCE(lo->lo_state)) != Lo_bound) {
> + srcu_read_unlock(&loop_io_srcu, idx);
> return BLK_STS_IOERR;
> + }
>
> switch (req_op(rq)) {
> case REQ_OP_FLUSH:
> @@ -1888,6 +1904,7 @@ static blk_status_t loop_queue_rq(struct blk_mq_hw_ctx *hctx,
> #endif
> loop_queue_work(lo, cmd);
>
> + srcu_read_unlock(&loop_io_srcu, idx);
> return BLK_STS_OK;
> }
Why SRCU instead of RCU? The loop driver doesn't set BLK_MQ_F_BLOCKING
and hence must not sleep inside loop_queue_rq(). Additionally, the block
layer already holds an RCU lock around all loop_queue_rq() calls. From
block/blk-mq.h:
/* run the code block in @dispatch_ops with rcu/srcu read lock held */
#define __blk_mq_run_dispatch_ops(q, check_sleep, dispatch_ops) \
do { \
if ((q)->tag_set->flags & BLK_MQ_F_BLOCKING) { \
struct blk_mq_tag_set *__tag_set = (q)->tag_set; \
int srcu_idx; \
\
might_sleep_if(check_sleep); \
srcu_idx = srcu_read_lock(__tag_set->srcu); \
(dispatch_ops); \
srcu_read_unlock(__tag_set->srcu, srcu_idx); \
} else { \
rcu_read_lock(); \
(dispatch_ops); \
rcu_read_unlock(); \
} \
} while (0)
Thanks,
Bart.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] loop: Fix NULL pointer dereference by synchronizing lo_release and loop_queue_rq
2026-05-11 15:58 ` Bart Van Assche
@ 2026-05-11 17:43 ` Tetsuo Handa
2026-05-12 11:46 ` Tetsuo Handa
0 siblings, 1 reply; 6+ messages in thread
From: Tetsuo Handa @ 2026-05-11 17:43 UTC (permalink / raw)
To: Bart Van Assche, Andrew Morton
Cc: Jens Axboe, linux-block, LKML, Christoph Hellwig, Damien Le Moal
Thank you for responding.
Given it is protected by RCU, this might be yet another manifestation of
"is trying to release lock (rcu_read_lock) at:" + "but there are no more locks to release!"-type of
hidden RCU imbalance bugs recently introduced? Andrew, was any progress made for RCU imbalance bugs?
On 2026/04/21 20:05, Tetsuo Handa wrote:
> Since this problem started after the merge window opened, the culprit commit
> might be in between commit a028739a4330 ("Merge tag 'block-7.0-20260305' of
> git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux") and
> commit 7fe6ac157b7e ("Merge tag 'for-7.1/block-20260411' of
> git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux").
> Also, syzbot was not testing changes in linux-next since next-20260403,
> and found this problem in next-20260413.
On 2026/05/12 0:58, Bart Van Assche wrote:
> Why SRCU instead of RCU? The loop driver doesn't set BLK_MQ_F_BLOCKING
> and hence must not sleep inside loop_queue_rq(). Additionally, the block
> layer already holds an RCU lock around all loop_queue_rq() calls. From
> block/blk-mq.h:
>
> /* run the code block in @dispatch_ops with rcu/srcu read lock held */
> #define __blk_mq_run_dispatch_ops(q, check_sleep, dispatch_ops) \
> do { \
> if ((q)->tag_set->flags & BLK_MQ_F_BLOCKING) { \
> struct blk_mq_tag_set *__tag_set = (q)->tag_set; \
> int srcu_idx; \
> \
> might_sleep_if(check_sleep); \
> srcu_idx = srcu_read_lock(__tag_set->srcu); \
> (dispatch_ops); \
> srcu_read_unlock(__tag_set->srcu, srcu_idx); \
> } else { \
> rcu_read_lock(); \
> (dispatch_ops); \
> rcu_read_unlock(); \
> } \
> } while (0)
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] loop: Fix NULL pointer dereference by synchronizing lo_release and loop_queue_rq
2026-05-11 17:43 ` Tetsuo Handa
@ 2026-05-12 11:46 ` Tetsuo Handa
0 siblings, 0 replies; 6+ messages in thread
From: Tetsuo Handa @ 2026-05-12 11:46 UTC (permalink / raw)
To: Bart Van Assche
Cc: Jens Axboe, linux-block, LKML, Christoph Hellwig, Damien Le Moal,
Andrew Morton
Commit 99ebc509eef5 ("mm: memcontrol: fix rcu unbalance in get_non_dying_memcg_end()") fixed
RCU imbalance bug, and it seems that so far only trees without that commit is reproducing RCU
imbalance bug.
But since this NULL pointer dereference bug was reproduced in linux-next-20260508 which already
includes that commit, I suspect that some change in the block layer broke protection by RCU
synchronization or flushing of lo->workqueue.
Can you check that there was no commit that might break protection by RCU synchronization or
flushing of lo->workqueue?
On 2026/05/12 2:43, Tetsuo Handa wrote:
> Thank you for responding.
>
> Given it is protected by RCU, this might be yet another manifestation of
> "is trying to release lock (rcu_read_lock) at:" + "but there are no more locks to release!"-type of
> hidden RCU imbalance bugs recently introduced? Andrew, was any progress made for RCU imbalance bugs?
>
> On 2026/04/21 20:05, Tetsuo Handa wrote:
>> Since this problem started after the merge window opened, the culprit commit
>> might be in between commit a028739a4330 ("Merge tag 'block-7.0-20260305' of
>> git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux") and
>> commit 7fe6ac157b7e ("Merge tag 'for-7.1/block-20260411' of
>> git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux").
>> Also, syzbot was not testing changes in linux-next since next-20260403,
>> and found this problem in next-20260413.
>
> On 2026/05/12 0:58, Bart Van Assche wrote:
>> Why SRCU instead of RCU? The loop driver doesn't set BLK_MQ_F_BLOCKING
>> and hence must not sleep inside loop_queue_rq(). Additionally, the block
>> layer already holds an RCU lock around all loop_queue_rq() calls. From
>> block/blk-mq.h:
>>
>> /* run the code block in @dispatch_ops with rcu/srcu read lock held */
>> #define __blk_mq_run_dispatch_ops(q, check_sleep, dispatch_ops) \
>> do { \
>> if ((q)->tag_set->flags & BLK_MQ_F_BLOCKING) { \
>> struct blk_mq_tag_set *__tag_set = (q)->tag_set; \
>> int srcu_idx; \
>> \
>> might_sleep_if(check_sleep); \
>> srcu_idx = srcu_read_lock(__tag_set->srcu); \
>> (dispatch_ops); \
>> srcu_read_unlock(__tag_set->srcu, srcu_idx); \
>> } else { \
>> rcu_read_lock(); \
>> (dispatch_ops); \
>> rcu_read_unlock(); \
>> } \
>> } while (0)
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-05-12 11:48 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-18 0:02 [syzbot] [block?] general protection fault in lo_rw_aio syzbot
2026-04-21 11:05 ` Tetsuo Handa
2026-05-11 11:43 ` [PATCH] loop: Fix NULL pointer dereference by synchronizing lo_release and loop_queue_rq Tetsuo Handa
2026-05-11 15:58 ` Bart Van Assche
2026-05-11 17:43 ` Tetsuo Handa
2026-05-12 11:46 ` Tetsuo Handa
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox