mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [syzbot] [fs?] possible deadlock in ovl_create_object (2)
@ 2026-09-09 15:19 syzbot
  2026-09-12 13:12 ` syzbot
  2026-09-16 19:48 ` Chris Roy
  0 siblings, 2 replies; 10+ messages in thread
From: syzbot @ 2026-09-09 15:19 UTC (permalink / raw)
  To: dakr, driver-core, gregkh, linux-fsdevel, linux-kernel, rafael,
	syzkaller-bugs

Hello,

syzbot found the following issue on:

HEAD commit:    654ae5d73c05 Merge tag 'drm-fixes-2026-09-05' of https://g..
git tree:       upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=11860cf9580000
kernel config:  https://syzkaller.appspot.com/x/.config?x=8c5c3949d762a91f
dashboard link: https://syzkaller.appspot.com/bug?extid=7cab6a19619f1b8efc00
compiler:       gcc (Debian 14.2.0-19) 14.2.0, GNU ld (GNU Binutils for Debian) 2.44

Unfortunately, I don't have any reproducer for this issue yet.

Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/90a1eb1b2bfe/disk-654ae5d7.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/dcbbe9cf09c5/vmlinux-654ae5d7.xz
kernel image: https://storage.googleapis.com/syzbot-assets/c80eca6821dd/bzImage-654ae5d7.xz

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+7cab6a19619f1b8efc00@syzkaller.appspotmail.com

======================================================
WARNING: possible circular locking dependency detected
syzkaller #0 Tainted: G             L     
------------------------------------------------------
syz.6.857/9678 is trying to acquire lock:
ffff88803cd16460 (sb_writers#6){.+.+}-{0:0}, at: ovl_create_object+0x130/0x3b0 fs/overlayfs/dir.c:705

but task is already holding lock:
ffff888058c6e948 (&ovl_i_mutex_dir_key[depth]){++++}-{4:4}, at: inode_lock include/linux/fs.h:1024 [inline]
ffff888058c6e948 (&ovl_i_mutex_dir_key[depth]){++++}-{4:4}, at: lookup_open+0xb13/0x1990 fs/namei.c:4458

which lock already depends on the new lock.


the existing dependency chain (in reverse order) is:

-> #4 (&ovl_i_mutex_dir_key[depth]){++++}-{4:4}:
       lock_acquire kernel/locking/lockdep.c:5908 [inline]
       lock_acquire+0x1d1/0x380 kernel/locking/lockdep.c:5865
       down_read+0x99/0x4c0 kernel/locking/rwsem.c:1574
       inode_lock_shared include/linux/fs.h:1039 [inline]
       lookup_slow+0x42/0x70 fs/namei.c:1935
       walk_component fs/namei.c:2282 [inline]
       lookup_last fs/namei.c:2789 [inline]
       path_lookupat+0x5e8/0xc40 fs/namei.c:2813
       filename_lookup+0x202/0x590 fs/namei.c:2842
       kern_path+0x37/0x50 fs/namei.c:3036
       lookup_bdev+0xd8/0x2a0 block/bdev.c:1268
       bdev_file_open_by_path+0x82/0x330 block/bdev.c:1123
       add_device drivers/mtd/devices/block2mtd.c:279 [inline]
       block2mtd_setup2.isra.0+0x2ee/0xbd0 drivers/mtd/devices/block2mtd.c:459
       block2mtd_setup+0xbd/0xd0 drivers/mtd/devices/block2mtd.c:476
       param_attr_store+0x199/0x300 kernel/params.c:591
       module_attr_store+0x58/0x80 kernel/params.c:906
       sysfs_kf_write+0xf2/0x150 fs/sysfs/file.c:145
       kernfs_fop_write_iter+0x3e0/0x5f0 fs/kernfs/file.c:345
       new_sync_write fs/read_write.c:595 [inline]
       vfs_write+0x6af/0x1050 fs/read_write.c:687
       ksys_write+0x12a/0x250 fs/read_write.c:739
       do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
       do_syscall_64+0x123/0x790 arch/x86/entry/syscall_64.c:84
       entry_SYSCALL_64_after_hwframe+0x77/0x7f

-> #3 (param_lock){+.+.}-{4:4}:
       lock_acquire kernel/locking/lockdep.c:5908 [inline]
       lock_acquire+0x1d1/0x380 kernel/locking/lockdep.c:5865
       __mutex_lock_common kernel/locking/mutex.c:646 [inline]
       __mutex_lock+0x1a4/0x1bd0 kernel/locking/mutex.c:821
       ieee80211_rate_control_ops_get net/mac80211/rate.c:221 [inline]
       rate_control_alloc net/mac80211/rate.c:267 [inline]
       ieee80211_init_rate_ctrl_alg+0x1df/0x3b0 net/mac80211/rate.c:1008
       ieee80211_register_hw+0x2c1e/0x4580 net/mac80211/main.c:1561
       mac80211_hwsim_new_radio+0x2b08/0x6510 drivers/net/wireless/virtual/mac80211_hwsim_main.c:6138
       init_mac80211_hwsim+0x5e2/0x6f0 drivers/net/wireless/virtual/mac80211_hwsim_main.c:7624
       do_one_initcall+0x11c/0x6f0 init/main.c:1357
       do_initcall_level init/main.c:1419 [inline]
       do_initcalls init/main.c:1435 [inline]
       do_basic_setup init/main.c:1455 [inline]
       kernel_init_freeable+0x6ea/0x7b0 init/main.c:1670
       kernel_init+0x21/0x1e0 init/main.c:1560
       ret_from_fork+0x730/0xd60 arch/x86/kernel/process.c:158
       ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245

-> #2 (rtnl_mutex){+.+.}-{4:4}:
       lock_acquire kernel/locking/lockdep.c:5908 [inline]
       lock_acquire+0x1d1/0x380 kernel/locking/lockdep.c:5865
       __mutex_lock_common kernel/locking/mutex.c:646 [inline]
       __mutex_lock+0x1a4/0x1bd0 kernel/locking/mutex.c:821
       rtnl_lock net/core/rtnetlink.c:80 [inline]
       rtnetlink_rcv_msg+0x371/0xe90 net/core/rtnetlink.c:7138
       netlink_rcv_skb+0x159/0x420 net/netlink/af_netlink.c:2556
       netlink_unicast_kernel net/netlink/af_netlink.c:1319 [inline]
       netlink_unicast+0x585/0x850 net/netlink/af_netlink.c:1345
       netlink_sendmsg+0x8b0/0xda0 net/netlink/af_netlink.c:1900
       sock_sendmsg_nosec net/socket.c:800 [inline]
       __sock_sendmsg net/socket.c:815 [inline]
       sock_sendmsg+0x394/0x410 net/socket.c:838
       splice_to_socket+0xb3c/0x11a0 fs/splice.c:884
       do_splice_from fs/splice.c:936 [inline]
       do_splice+0x109c/0x1fa0 fs/splice.c:1349
       __do_splice+0x33b/0x370 fs/splice.c:1431
       __do_sys_splice fs/splice.c:1634 [inline]
       __se_sys_splice fs/splice.c:1616 [inline]
       __x64_sys_splice+0x187/0x250 fs/splice.c:1616
       do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
       do_syscall_64+0x123/0x790 arch/x86/entry/syscall_64.c:84
       entry_SYSCALL_64_after_hwframe+0x77/0x7f

-> #1 (&pipe->mutex){+.+.}-{4:4}:
       lock_acquire kernel/locking/lockdep.c:5908 [inline]
       lock_acquire+0x1d1/0x380 kernel/locking/lockdep.c:5865
       __mutex_lock_common kernel/locking/mutex.c:646 [inline]
       __mutex_lock+0x1a4/0x1bd0 kernel/locking/mutex.c:821
       pipe_lock fs/pipe.c:91 [inline]
       pipe_lock+0x69/0x80 fs/pipe.c:88
       iter_file_splice_write+0x1fd/0x10b0 fs/splice.c:682
       do_splice_from fs/splice.c:936 [inline]
       do_splice+0x109c/0x1fa0 fs/splice.c:1349
       __do_splice+0x33b/0x370 fs/splice.c:1431
       __do_sys_splice fs/splice.c:1634 [inline]
       __se_sys_splice fs/splice.c:1616 [inline]
       __x64_sys_splice+0x187/0x250 fs/splice.c:1616
       do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
       do_syscall_64+0x123/0x790 arch/x86/entry/syscall_64.c:84
       entry_SYSCALL_64_after_hwframe+0x77/0x7f

-> #0 (sb_writers#6){.+.+}-{0:0}:
       check_prev_add+0xeb/0xe60 kernel/locking/lockdep.c:3181
       check_prevs_add kernel/locking/lockdep.c:3300 [inline]
       validate_chain kernel/locking/lockdep.c:3924 [inline]
       __lock_acquire+0x1492/0x1ec0 kernel/locking/lockdep.c:5254
       lock_acquire kernel/locking/lockdep.c:5908 [inline]
       lock_acquire+0x1d1/0x380 kernel/locking/lockdep.c:5865
       percpu_down_read_internal include/linux/percpu-rwsem.h:53 [inline]
       percpu_down_read_freezable include/linux/percpu-rwsem.h:83 [inline]
       __sb_start_write include/linux/fs/super.h:19 [inline]
       sb_start_write include/linux/fs/super.h:125 [inline]
       mnt_want_write+0x6f/0x420 fs/namespace.c:494
       ovl_create_object+0x130/0x3b0 fs/overlayfs/dir.c:705
       lookup_open+0x1255/0x1990 fs/namei.c:4567
       open_last_lookups fs/namei.c:4767 [inline]
       path_openat+0xa2c/0x2440 fs/namei.c:4997
       do_file_open+0x20e/0x430 fs/namei.c:5029
       do_sys_openat2+0x10f/0x1e0 fs/open.c:1417
       do_sys_open fs/open.c:1423 [inline]
       __do_sys_openat fs/open.c:1439 [inline]
       __se_sys_openat fs/open.c:1434 [inline]
       __x64_sys_openat+0x12d/0x210 fs/open.c:1434
       do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
       do_syscall_64+0x123/0x790 arch/x86/entry/syscall_64.c:84
       entry_SYSCALL_64_after_hwframe+0x77/0x7f

other info that might help us debug this:

Chain exists of:
  sb_writers#6 --> param_lock --> &ovl_i_mutex_dir_key[depth]

 Possible unsafe locking scenario:

       CPU0                    CPU1
       ----                    ----
  lock(&ovl_i_mutex_dir_key[depth]);
                               lock(param_lock);
                               lock(&ovl_i_mutex_dir_key[depth]);
  rlock(sb_writers#6);

 *** DEADLOCK ***

locks held by syz.6.857/9678: 2, last CPU#1:
 #0: ffff88802ba66460 (sb_writers#13){.+.+}-{0:0}, at: lookup_open+0x150/0x1990 fs/namei.c:4451
 #1: ffff888058c6e948 (&ovl_i_mutex_dir_key[depth]){++++}-{4:4}, at: inode_lock include/linux/fs.h:1024 [inline]
 #1: ffff888058c6e948 (&ovl_i_mutex_dir_key[depth]){++++}-{4:4}, at: lookup_open+0xb13/0x1990 fs/namei.c:4458

stack backtrace:
CPU: 1 UID: 0 PID: 9678 Comm: syz.6.857 Tainted: G             L      syzkaller #0 PREEMPT(full) 
Tainted: [L]=SOFTLOCKUP
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/05/2026
Call Trace:
 <TASK>
 __dump_stack lib/dump_stack.c:94 [inline]
 dump_stack_lvl+0x100/0x190 lib/dump_stack.c:120
 print_circular_bug.cold+0x178/0x1be kernel/locking/lockdep.c:2059
 check_noncircular+0x146/0x160 kernel/locking/lockdep.c:2191
 check_prev_add+0xeb/0xe60 kernel/locking/lockdep.c:3181
 check_prevs_add kernel/locking/lockdep.c:3300 [inline]
 validate_chain kernel/locking/lockdep.c:3924 [inline]
 __lock_acquire+0x1492/0x1ec0 kernel/locking/lockdep.c:5254
 lock_acquire kernel/locking/lockdep.c:5908 [inline]
 lock_acquire+0x1d1/0x380 kernel/locking/lockdep.c:5865
 percpu_down_read_internal include/linux/percpu-rwsem.h:53 [inline]
 percpu_down_read_freezable include/linux/percpu-rwsem.h:83 [inline]
 __sb_start_write include/linux/fs/super.h:19 [inline]
 sb_start_write include/linux/fs/super.h:125 [inline]
 mnt_want_write+0x6f/0x420 fs/namespace.c:494
 ovl_create_object+0x130/0x3b0 fs/overlayfs/dir.c:705
 lookup_open+0x1255/0x1990 fs/namei.c:4567
 open_last_lookups fs/namei.c:4767 [inline]
 path_openat+0xa2c/0x2440 fs/namei.c:4997
 do_file_open+0x20e/0x430 fs/namei.c:5029
 do_sys_openat2+0x10f/0x1e0 fs/open.c:1417
 do_sys_open fs/open.c:1423 [inline]
 __do_sys_openat fs/open.c:1439 [inline]
 __se_sys_openat fs/open.c:1434 [inline]
 __x64_sys_openat+0x12d/0x210 fs/open.c:1434
 do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
 do_syscall_64+0x123/0x790 arch/x86/entry/syscall_64.c:84
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f2d2539e159
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f2d261d2028 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
RAX: ffffffffffffffda RBX: 00007f2d25625fa0 RCX: 00007f2d2539e159
RDX: 0000000000000040 RSI: 0000200000000180 RDI: ffffffffffffff9c
RBP: 00007f2d25435024 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000023 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f2d25626038 R14: 00007f2d25625fa0 R15: 00007ffeef1e4b18
 </TASK>


---
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] 10+ messages in thread

* Re: [syzbot] [fs?] possible deadlock in ovl_create_object (2)
  2026-09-09 15:19 [syzbot] [fs?] possible deadlock in ovl_create_object (2) syzbot
@ 2026-09-12 13:12 ` syzbot
  2026-09-16 19:48 ` Chris Roy
  1 sibling, 0 replies; 10+ messages in thread
From: syzbot @ 2026-09-12 13:12 UTC (permalink / raw)
  To: dakr, driver-core, gregkh, linux-fsdevel, linux-kernel, rafael,
	syzkaller-bugs

syzbot has found a reproducer for the following issue on:

HEAD commit:    5225b8eec4c9 mailmap: update entry for Jens Axboe
git tree:       git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
console output: https://syzkaller.appspot.com/x/log.txt?x=104c82d1580000
kernel config:  https://syzkaller.appspot.com/x/.config?x=8c5c3949d762a91f
dashboard link: https://syzkaller.appspot.com/bug?extid=7cab6a19619f1b8efc00
compiler:       gcc (Debian 14.2.0-19) 14.2.0, GNU ld (GNU Binutils for Debian) 2.44
C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=144c82d1580000

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+7cab6a19619f1b8efc00@syzkaller.appspotmail.com

block2mtd: error: cannot open device /tmp/ovl_bug_7ivaQs/merged/nonexistent
======================================================
WARNING: possible circular locking dependency detected
syzkaller #0 Not tainted
------------------------------------------------------
syz-executor469/6041 is trying to acquire lock:
ffff888024d8c460 (sb_writers#6){.+.+}-{0:0}, at: ovl_create_object+0x130/0x3b0 fs/overlayfs/dir.c:705

but task is already holding lock:
ffff88805802a7a8 (&ovl_i_mutex_dir_key[depth]){++++}-{4:4}, at: inode_lock include/linux/fs.h:1024 [inline]
ffff88805802a7a8 (&ovl_i_mutex_dir_key[depth]){++++}-{4:4}, at: lookup_open+0xb13/0x1990 fs/namei.c:4458

which lock already depends on the new lock.


the existing dependency chain (in reverse order) is:

-> #4 (&ovl_i_mutex_dir_key[depth]){++++}-{4:4}:
       lock_acquire kernel/locking/lockdep.c:5942 [inline]
       lock_acquire+0x1d1/0x380 kernel/locking/lockdep.c:5899
       down_read+0x99/0x4c0 kernel/locking/rwsem.c:1574
       inode_lock_shared include/linux/fs.h:1039 [inline]
       lookup_slow+0x42/0x70 fs/namei.c:1935
       walk_component fs/namei.c:2282 [inline]
       lookup_last fs/namei.c:2789 [inline]
       path_lookupat+0x5e8/0xc40 fs/namei.c:2813
       filename_lookup+0x202/0x590 fs/namei.c:2842
       kern_path+0x37/0x50 fs/namei.c:3036
       lookup_bdev+0xd8/0x2a0 block/bdev.c:1268
       bdev_file_open_by_path+0x82/0x330 block/bdev.c:1123
       add_device drivers/mtd/devices/block2mtd.c:279 [inline]
       block2mtd_setup2.isra.0+0x2ee/0xbd0 drivers/mtd/devices/block2mtd.c:459
       block2mtd_setup+0xbd/0xd0 drivers/mtd/devices/block2mtd.c:476
       param_attr_store+0x199/0x300 kernel/params.c:591
       module_attr_store+0x58/0x80 kernel/params.c:906
       sysfs_kf_write+0xf2/0x150 fs/sysfs/file.c:145
       kernfs_fop_write_iter+0x3e0/0x5f0 fs/kernfs/file.c:345
       iter_file_splice_write+0x830/0x10b0 fs/splice.c:736
       do_splice_from fs/splice.c:936 [inline]
       do_splice+0x109c/0x1fa0 fs/splice.c:1349
       __do_splice+0x33b/0x370 fs/splice.c:1431
       __do_sys_splice fs/splice.c:1634 [inline]
       __se_sys_splice fs/splice.c:1616 [inline]
       __x64_sys_splice+0x187/0x250 fs/splice.c:1616
       do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
       do_syscall_64+0x123/0x790 arch/x86/entry/syscall_64.c:84
       entry_SYSCALL_64_after_hwframe+0x77/0x7f

-> #3 (param_lock){+.+.}-{4:4}:
       lock_acquire kernel/locking/lockdep.c:5942 [inline]
       lock_acquire+0x1d1/0x380 kernel/locking/lockdep.c:5899
       __mutex_lock_common kernel/locking/mutex.c:646 [inline]
       __mutex_lock+0x1a4/0x1bd0 kernel/locking/mutex.c:821
       kernel_param_lock kernel/params.c:604 [inline]
       param_attr_store+0xec/0x300 kernel/params.c:589
       module_attr_store+0x58/0x80 kernel/params.c:906
       sysfs_kf_write+0xf2/0x150 fs/sysfs/file.c:145
       kernfs_fop_write_iter+0x3e0/0x5f0 fs/kernfs/file.c:345
       new_sync_write fs/read_write.c:595 [inline]
       vfs_write+0x6af/0x1050 fs/read_write.c:687
       ksys_write+0x12a/0x250 fs/read_write.c:739
       do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
       do_syscall_64+0x123/0x790 arch/x86/entry/syscall_64.c:84
       entry_SYSCALL_64_after_hwframe+0x77/0x7f

-> #2 (&of->mutex){+.+.}-{4:4}:
       lock_acquire kernel/locking/lockdep.c:5942 [inline]
       lock_acquire+0x1d1/0x380 kernel/locking/lockdep.c:5899
       __mutex_lock_common kernel/locking/mutex.c:646 [inline]
       __mutex_lock+0x1a4/0x1bd0 kernel/locking/mutex.c:821
       kernfs_fop_write_iter+0x2c2/0x5f0 fs/kernfs/file.c:336
       iter_file_splice_write+0x830/0x10b0 fs/splice.c:736
       do_splice_from fs/splice.c:936 [inline]
       do_splice+0x109c/0x1fa0 fs/splice.c:1349
       __do_splice+0x33b/0x370 fs/splice.c:1431
       __do_sys_splice fs/splice.c:1634 [inline]
       __se_sys_splice fs/splice.c:1616 [inline]
       __x64_sys_splice+0x187/0x250 fs/splice.c:1616
       do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
       do_syscall_64+0x123/0x790 arch/x86/entry/syscall_64.c:84
       entry_SYSCALL_64_after_hwframe+0x77/0x7f

-> #1 (&pipe->mutex){+.+.}-{4:4}:
       lock_acquire kernel/locking/lockdep.c:5942 [inline]
       lock_acquire+0x1d1/0x380 kernel/locking/lockdep.c:5899
       __mutex_lock_common kernel/locking/mutex.c:646 [inline]
       __mutex_lock+0x1a4/0x1bd0 kernel/locking/mutex.c:821
       pipe_lock fs/pipe.c:91 [inline]
       pipe_lock+0x69/0x80 fs/pipe.c:88
       iter_file_splice_write+0x1fd/0x10b0 fs/splice.c:682
       do_splice_from fs/splice.c:936 [inline]
       do_splice+0x109c/0x1fa0 fs/splice.c:1349
       __do_splice+0x33b/0x370 fs/splice.c:1431
       __do_sys_splice fs/splice.c:1634 [inline]
       __se_sys_splice fs/splice.c:1616 [inline]
       __x64_sys_splice+0x187/0x250 fs/splice.c:1616
       do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
       do_syscall_64+0x123/0x790 arch/x86/entry/syscall_64.c:84
       entry_SYSCALL_64_after_hwframe+0x77/0x7f

-> #0 (sb_writers#6){.+.+}-{0:0}:
       check_prev_add+0xeb/0xe60 kernel/locking/lockdep.c:3209
       check_prevs_add kernel/locking/lockdep.c:3328 [inline]
       validate_chain kernel/locking/lockdep.c:3952 [inline]
       __lock_acquire+0x1528/0x1f40 kernel/locking/lockdep.c:5288
       lock_acquire kernel/locking/lockdep.c:5942 [inline]
       lock_acquire+0x1d1/0x380 kernel/locking/lockdep.c:5899
       percpu_down_read_internal include/linux/percpu-rwsem.h:53 [inline]
       percpu_down_read_freezable include/linux/percpu-rwsem.h:83 [inline]
       __sb_start_write include/linux/fs/super.h:19 [inline]
       sb_start_write include/linux/fs/super.h:125 [inline]
       mnt_want_write+0x6f/0x420 fs/namespace.c:494
       ovl_create_object+0x130/0x3b0 fs/overlayfs/dir.c:705
       lookup_open+0x1255/0x1990 fs/namei.c:4567
       open_last_lookups fs/namei.c:4767 [inline]
       path_openat+0xa2c/0x2440 fs/namei.c:4997
       do_file_open+0x20e/0x430 fs/namei.c:5029
       do_sys_openat2+0x10f/0x1e0 fs/open.c:1417
       do_sys_open fs/open.c:1423 [inline]
       __do_sys_openat fs/open.c:1439 [inline]
       __se_sys_openat fs/open.c:1434 [inline]
       __x64_sys_openat+0x12d/0x210 fs/open.c:1434
       do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
       do_syscall_64+0x123/0x790 arch/x86/entry/syscall_64.c:84
       entry_SYSCALL_64_after_hwframe+0x77/0x7f

other info that might help us debug this:

Chain exists of:
  sb_writers#6 --> param_lock --> &ovl_i_mutex_dir_key[depth]

 Possible unsafe locking scenario:

       CPU0                    CPU1
       ----                    ----
  lock(&ovl_i_mutex_dir_key[depth]);
                               lock(param_lock);
                               lock(&ovl_i_mutex_dir_key[depth]);
  rlock(sb_writers#6);

 *** DEADLOCK ***

locks held by syz-executor469/6041: 2, last CPU#2:
 #0: ffff88802a68c460 (sb_writers#13){.+.+}-{0:0}, at: lookup_open+0x150/0x1990 fs/namei.c:4451
 #1: ffff88805802a7a8 (&ovl_i_mutex_dir_key[depth]){++++}-{4:4}, at: inode_lock include/linux/fs.h:1024 [inline]
 #1: ffff88805802a7a8 (&ovl_i_mutex_dir_key[depth]){++++}-{4:4}, at: lookup_open+0xb13/0x1990 fs/namei.c:4458

stack backtrace:
CPU: 2 UID: 0 PID: 6041 Comm: syz-executor469 Not tainted syzkaller #0 PREEMPT(full) 
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Call Trace:
 <TASK>
 __dump_stack lib/dump_stack.c:94 [inline]
 dump_stack_lvl+0x100/0x190 lib/dump_stack.c:120
 print_circular_bug.cold+0x178/0x1be kernel/locking/lockdep.c:2087
 check_noncircular+0x146/0x160 kernel/locking/lockdep.c:2219
 check_prev_add+0xeb/0xe60 kernel/locking/lockdep.c:3209
 check_prevs_add kernel/locking/lockdep.c:3328 [inline]
 validate_chain kernel/locking/lockdep.c:3952 [inline]
 __lock_acquire+0x1528/0x1f40 kernel/locking/lockdep.c:5288
 lock_acquire kernel/locking/lockdep.c:5942 [inline]
 lock_acquire+0x1d1/0x380 kernel/locking/lockdep.c:5899
 percpu_down_read_internal include/linux/percpu-rwsem.h:53 [inline]
 percpu_down_read_freezable include/linux/percpu-rwsem.h:83 [inline]
 __sb_start_write include/linux/fs/super.h:19 [inline]
 sb_start_write include/linux/fs/super.h:125 [inline]
 mnt_want_write+0x6f/0x420 fs/namespace.c:494
 ovl_create_object+0x130/0x3b0 fs/overlayfs/dir.c:705
 lookup_open+0x1255/0x1990 fs/namei.c:4567
 open_last_lookups fs/namei.c:4767 [inline]
 path_openat+0xa2c/0x2440 fs/namei.c:4997
 do_file_open+0x20e/0x430 fs/namei.c:5029
 do_sys_openat2+0x10f/0x1e0 fs/open.c:1417
 do_sys_open fs/open.c:1423 [inline]
 __do_sys_openat fs/open.c:1439 [inline]
 __se_sys_openat fs/open.c:1434 [inline]
 __x64_sys_openat+0x12d/0x210 fs/open.c:1434
 do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
 do_syscall_64+0x123/0x790 arch/x86/entry/syscall_64.c:84
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fadca23e437
Code: 48 89 fa 4c 89 df e8 98 1d 00 00 8b 93 08 03 00 00 59 5e 48 83 f8 fc 74 1a 5b c3 0f 1f 84 00 00 00 00 00 48 8b 44 24 10 0f 05 <5b> c3 0f 1f 80 00 00 00 00 83 e2 39 83 fa 08 75 de e8 23 ff ff ff
RSP: 002b:00007fff380044d0 EFLAGS: 00000202 ORIG_RAX: 0000000000000101
RAX: ffffffffffffffda RBX: 000055555dddf400 RCX: 00007fadca23e437
RDX: 0000000000000042 RSI: 00007fadca277192 RDI: ffffffffffffff9c
RBP: 00007fadca2770fe R08: 0000000000000000 R09: 0000000000000000
R10: 00000000000001a4 R11: 0000000000000202 R12: 000055555dde1770
R13: 0000000000000026 R14: 00007fff380045a0 R15: 0000000000000002
 </TASK>


---
If you want syzbot to run the reproducer, reply with:
#syz test: git://repo/address.git branch-or-commit-hash
If you attach or paste a git patch, syzbot will apply it before testing.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [syzbot] [fs?] possible deadlock in ovl_create_object (2)
  2026-09-09 15:19 [syzbot] [fs?] possible deadlock in ovl_create_object (2) syzbot
  2026-09-12 13:12 ` syzbot
@ 2026-09-16 19:48 ` Chris Roy
  2026-09-16 21:37   ` Chris Roy
  1 sibling, 1 reply; 10+ messages in thread
From: Chris Roy @ 2026-09-16 19:48 UTC (permalink / raw)
  To: syzbot
  Cc: dakr, driver-core, gregkh, linux-fsdevel, linux-kernel, rafael,
	syzkaller-bugs

On Thu, 17 Sept 2026 at 01:10, syzbot
<syzbot+7cab6a19619f1b8efc00@syzkaller.appspotmail.com> wrote:
>
> Hello,
>
> syzbot found the following issue on:
>
> HEAD commit:    654ae5d73c05 Merge tag 'drm-fixes-2026-09-05' of https://g..
> git tree:       upstream
> console output: https://syzkaller.appspot.com/x/log.txt?x=11860cf9580000
> kernel config:  https://syzkaller.appspot.com/x/.config?x=8c5c3949d762a91f
> dashboard link: https://syzkaller.appspot.com/bug?extid=7cab6a19619f1b8efc00
> compiler:       gcc (Debian 14.2.0-19) 14.2.0, GNU ld (GNU Binutils for Debian) 2.44
>
> Unfortunately, I don't have any reproducer for this issue yet.

I am investigating this report and working on reproducing the lockdep
cycle and identifying the root cause. I will follow up with findings
and a proposed fix shortly.

Regards,
- Chris

"But how could you live and have no story to tell?"

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [syzbot] [fs?] possible deadlock in ovl_create_object (2)
  2026-09-16 19:48 ` Chris Roy
@ 2026-09-16 21:37   ` Chris Roy
  2026-09-16 21:52     ` syzbot
  0 siblings, 1 reply; 10+ messages in thread
From: Chris Roy @ 2026-09-16 21:37 UTC (permalink / raw)
  To: syzbot
  Cc: dakr, driver-core, gregkh, linux-fsdevel, linux-kernel, rafael,
	syzkaller-bugs

[-- Attachment #1: Type: text/plain, Size: 1907 bytes --]

On Wed, 9 Sep 2026 08:19:24 -0700, syzbot wrote:
> syzbot found the following issue on:
> ...
> possible deadlock in ovl_create_object

Follow-up to my earlier note: I reproduced this with the C reproducer.

The cycle is not an overlayfs bug by itself. block2mtd_setup() opens the
named block device (VFS path walk) while still under param_lock and the
kernfs write path. When that write arrives via splice, a pipe mutex is
held as well. That nests under already (the other way) ordered locks with
overlay sb_writers / ovl_i_mutex.

The attached patch drops param_lock and defers the open to a workqueue
(still synchronous via wait_for_completion), so the VFS walk does not
run under that stack. Local testing with the syzbot C repro: lockdep
warning before the patch, clean after.

#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
master

Please consider the patch for linux-mtd.

On Thu, 17 Sept 2026 at 01:18, Chris Roy <iam@thechris.in> wrote:
>
> On Thu, 17 Sept 2026 at 01:10, syzbot
> <syzbot+7cab6a19619f1b8efc00@syzkaller.appspotmail.com> wrote:
> >
> > Hello,
> >
> > syzbot found the following issue on:
> >
> > HEAD commit:    654ae5d73c05 Merge tag 'drm-fixes-2026-09-05' of https://g..
> > git tree:       upstream
> > console output: https://syzkaller.appspot.com/x/log.txt?x=11860cf9580000
> > kernel config:  https://syzkaller.appspot.com/x/.config?x=8c5c3949d762a91f
> > dashboard link: https://syzkaller.appspot.com/bug?extid=7cab6a19619f1b8efc00
> > compiler:       gcc (Debian 14.2.0-19) 14.2.0, GNU ld (GNU Binutils for Debian) 2.44
> >
> > Unfortunately, I don't have any reproducer for this issue yet.
>
> I am investigating this report and working on reproducing the lockdep
> cycle and identifying the root cause. I will follow up with findings
> and a proposed fix shortly.
>
> Regards,
> - Chris
>
> "But how could you live and have no story to tell?"

[-- Attachment #2: 0001-mtd-block2mtd-defer-device-open-out-of-param-sysfs-w.patch --]
[-- Type: text/x-diff, Size: 6155 bytes --]

From c39535066f53d998c716488273e86761bb8e2ade Mon Sep 17 00:00:00 2001
From: Chris Roy <iam@thechris.in>
Date: Wed, 16 Sep 2026 21:09:49 +0000
Subject: [PATCH] mtd: block2mtd: defer device open out of param/sysfs write

block2mtd_setup() is called from the module-parameter write path
while param_lock is held, and from inside kernfs_fop_write_iter
(which holds the kernfs inode mutex). When that write arrives via
splice, a pipe mutex is held as well.

The setup path then opens the named block device with
bdev_file_open_by_path(), which walks the VFS. That nests inode /
overlay directory locks and sb_writers under the locks above and
creates a lockdep cycle, for example:

  sb_writers -> pipe -> kernfs/param -> ovl_i_mutex -> sb_writers

syzbot reproduces it by splicing into an overlay file, splicing an
overlay path into /sys/module/block2mtd/parameters/block2mtd, then
creating a file on the overlay.

Drop param_lock and run the open on a workqueue so VFS locking is
not nested under the parameter/sysfs/pipe stack. Keep the call
synchronous with wait_for_completion(). Protect the device list and
the early-boot paramline buffer with a local mutex that is never
held across a path lookup.

Reported-by: syzbot+7cab6a19619f1b8efc00@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=7cab6a19619f1b8efc00
Signed-off-by: Chris Roy <iam@thechris.in>
---
 drivers/mtd/devices/block2mtd.c | 103 +++++++++++++++++++++++++-------
 1 file changed, 83 insertions(+), 20 deletions(-)

diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index 03e80b2c4..4ab4c31a2 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -27,6 +27,8 @@
 #include <linux/init.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mutex.h>
+#include <linux/workqueue.h>
+#include <linux/completion.h>
 #include <linux/mount.h>
 #include <linux/slab.h>
 #include <linux/major.h>
@@ -45,6 +47,7 @@ struct block2mtd_dev {
 
 /* Static info about the MTD, used in cleanup_module */
 static LIST_HEAD(blkmtd_device_list);
+static DEFINE_MUTEX(block2mtd_mutex);
 
 
 static struct page *page_read(struct address_space *mapping, pgoff_t index)
@@ -329,7 +332,9 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size,
 		goto err_destroy_mutex;
 	}
 
+	mutex_lock(&block2mtd_mutex);
 	list_add(&dev->list, &blkmtd_device_list);
+	mutex_unlock(&block2mtd_mutex);
 	pr_info("mtd%d: [%s] erase_size = %dKiB [%d]\n",
 		dev->mtd.index,
 		label ? label : dev->mtd.name + strlen("block2mtd: "),
@@ -462,30 +467,77 @@ static int block2mtd_setup2(const char *val)
 }
 
 
-static int block2mtd_setup(const char *val, const struct kernel_param *kp)
+
+struct block2mtd_setup_work {
+	struct work_struct work;
+	char *val;
+	struct completion done;
+	int ret;
+};
+
+static void block2mtd_setup_workfn(struct work_struct *work)
 {
-#ifdef MODULE
-	return block2mtd_setup2(val);
-#else
-	/* If more parameters are later passed in via
-	   /sys/module/block2mtd/parameters/block2mtd
-	   and block2mtd_init() has already been called,
-	   we can parse the argument now. */
+	struct block2mtd_setup_work *w =
+		container_of(work, struct block2mtd_setup_work, work);
+
+	w->ret = block2mtd_setup2(w->val);
+	complete(&w->done);
+}
+
+/*
+ * Run device setup outside the module-parameter / kernfs write path.
+ * Those paths hold param_lock and the kernfs inode mutex (and, when the
+ * write arrives via splice, a pipe mutex). Opening a block device does
+ * VFS lookups and must not nest under that stack.
+ */
+static int block2mtd_setup_defer(const char *val)
+{
+	struct block2mtd_setup_work w = {
+		.ret = 0,
+	};
+
+	w.val = kstrdup(val, GFP_KERNEL);
+	if (!w.val)
+		return -ENOMEM;
+
+	init_completion(&w.done);
+	INIT_WORK(&w.work, block2mtd_setup_workfn);
+	schedule_work(&w.work);
+	wait_for_completion(&w.done);
+	kfree(w.val);
+	return w.ret;
+}
 
-	if (block2mtd_init_called)
-		return block2mtd_setup2(val);
+static int block2mtd_setup(const char *val, const struct kernel_param *kp)
+{
+	int ret = 0;
 
-	/* During early boot stage, we only save the parameters
-	   here. We must parse them later: if the param passed
-	   from kernel boot command line, block2mtd_setup() is
-	   called so early that it is not possible to resolve
-	   the device (even kmalloc() fails). Deter that work to
-	   block2mtd_setup2(). */
+	if (!try_module_get(kp->mod))
+		return -ENODEV;
 
-	strscpy(block2mtd_paramline, val, sizeof(block2mtd_paramline));
+	/*
+	 * Drop param_lock before scheduling. The actual open runs on a
+	 * workqueue so it is also outside kernfs_fop_write_iter's inode
+	 * mutex (and any pipe lock from splice).
+	 */
+	kernel_param_unlock(kp->mod);
 
-	return 0;
+#ifdef MODULE
+	ret = block2mtd_setup_defer(val);
+#else
+	if (block2mtd_init_called) {
+		ret = block2mtd_setup_defer(val);
+	} else {
+		mutex_lock(&block2mtd_mutex);
+		strscpy(block2mtd_paramline, val, sizeof(block2mtd_paramline));
+		mutex_unlock(&block2mtd_mutex);
+	}
 #endif
+
+	kernel_param_lock(kp->mod);
+	module_put(kp->mod);
+
+	return ret;
 }
 
 
@@ -497,9 +549,18 @@ static int __init block2mtd_init(void)
 	int ret = 0;
 
 #ifndef MODULE
-	if (strlen(block2mtd_paramline))
-		ret = block2mtd_setup2(block2mtd_paramline);
+	mutex_lock(&block2mtd_mutex);
+	if (strlen(block2mtd_paramline)) {
+		char buf[sizeof(block2mtd_paramline)];
+
+		strscpy(buf, block2mtd_paramline, sizeof(buf));
+		mutex_unlock(&block2mtd_mutex);
+		/* init context: no kernfs/param locks held */
+		ret = block2mtd_setup2(buf);
+		mutex_lock(&block2mtd_mutex);
+	}
 	block2mtd_init_called = 1;
+	mutex_unlock(&block2mtd_mutex);
 #endif
 
 	return ret;
@@ -510,6 +571,7 @@ static void block2mtd_exit(void)
 {
 	struct list_head *pos, *next;
 
+	mutex_lock(&block2mtd_mutex);
 	/* Remove the MTD devices */
 	list_for_each_safe(pos, next, &blkmtd_device_list) {
 		struct block2mtd_dev *dev = list_entry(pos, typeof(*dev), list);
@@ -522,6 +584,7 @@ static void block2mtd_exit(void)
 		list_del(&dev->list);
 		block2mtd_free_device(dev);
 	}
+	mutex_unlock(&block2mtd_mutex);
 }
 
 late_initcall(block2mtd_init);
-- 
2.43.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [syzbot] [fs?] possible deadlock in ovl_create_object (2)
  2026-09-16 21:37   ` Chris Roy
@ 2026-09-16 21:52     ` syzbot
  2026-09-17  6:44       ` Chris Roy
  0 siblings, 1 reply; 10+ messages in thread
From: syzbot @ 2026-09-16 21:52 UTC (permalink / raw)
  To: dakr, driver-core, gregkh, iam, linux-fsdevel, linux-kernel,
	rafael, syzkaller-bugs

Hello,

syzbot has tested the proposed patch but the reproducer is still triggering an issue:
WARNING: ODEBUG bug in lookup_object_or_alloc

ODEBUG: object ffffc90007cdf850 is on stack ffffc90007cd8000, but NOT annotated.
------------[ cut here ]------------
1
WARNING: lib/debugobjects.c:672 at debug_object_is_on_stack lib/debugobjects.c:672 [inline], CPU#0: syz-executor162/6029
WARNING: lib/debugobjects.c:672 at lookup_object_or_alloc.part.0.cold+0x19/0x40 lib/debugobjects.c:705, CPU#0: syz-executor162/6029
Modules linked in:
CPU: 0 UID: 0 PID: 6029 Comm: syz-executor162 Not tainted syzkaller #0 PREEMPT(full) 
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
RIP: 0010:debug_object_is_on_stack lib/debugobjects.c:672 [inline]
RIP: 0010:lookup_object_or_alloc.part.0.cold+0x19/0x40 lib/debugobjects.c:705
Code: c4 60 5b 5d 41 5c 41 5d 41 5e 41 5f c3 cc cc cc cc 83 c5 01 89 2d a0 1f 7d 1a 4c 89 e6 48 c7 c7 c0 39 62 8c e8 21 ae eb ff 90 <0f> 0b 90 e9 82 31 fe 03 83 c5 01 89 2d 7f 1f 7d 1a 49 39 c4 73 da
RSP: 0018:ffffc90007cdf6c0 EFLAGS: 00010082
RAX: 0000000000000050 RBX: ffff88802cb1d738 RCX: 0000000000000000
RDX: 0000000000000050 RSI: ffffffff81ea1339 RDI: fffff52000f9bec9
RBP: 0000000000000001 R08: 0000000000000007 R09: 0000000000000000
R10: 8000000000000001 R11: 0000000000000001 R12: ffffc90007cdf850
R13: ffff888034204b00 R14: 0000000000000000 R15: 0000000000000000
FS:  00005555811b5400(0000) GS:ffff8880d5b57000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00005555811b8778 CR3: 000000002bbd8000 CR4: 0000000000352ef0
Call Trace:
 <TASK>
 lookup_object_or_alloc lib/debugobjects.c:682 [inline]
 __debug_object_init+0x2a9/0x3d0 lib/debugobjects.c:798
 __init_work+0x51/0x60 kernel/workqueue.c:697
 block2mtd_setup_defer+0xd7/0x1d0 drivers/mtd/devices/block2mtd.c:504
 block2mtd_setup+0x9c/0x1e0 drivers/mtd/devices/block2mtd.c:529
 param_attr_store+0x199/0x300 kernel/params.c:591
 module_attr_store+0x58/0x80 kernel/params.c:906
 sysfs_kf_write+0xf2/0x150 fs/sysfs/file.c:145
 kernfs_fop_write_iter+0x3e0/0x5f0 fs/kernfs/file.c:345
 iter_file_splice_write+0x830/0x10b0 fs/splice.c:736
 do_splice_from fs/splice.c:936 [inline]
 do_splice+0x109c/0x1fa0 fs/splice.c:1349
 __do_splice+0x33b/0x370 fs/splice.c:1431
 __do_sys_splice fs/splice.c:1634 [inline]
 __se_sys_splice fs/splice.c:1616 [inline]
 __x64_sys_splice+0x187/0x250 fs/splice.c:1616
 do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
 do_syscall_64+0x123/0x790 arch/x86/entry/syscall_64.c:84
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fa1c31b3437
Code: 48 89 fa 4c 89 df e8 98 1d 00 00 8b 93 08 03 00 00 59 5e 48 83 f8 fc 74 1a 5b c3 0f 1f 84 00 00 00 00 00 48 8b 44 24 10 0f 05 <5b> c3 0f 1f 80 00 00 00 00 83 e2 39 83 fa 08 75 de e8 23 ff ff ff
RSP: 002b:00007ffce5a2ac20 EFLAGS: 00000202 ORIG_RAX: 0000000000000113
RAX: ffffffffffffffda RBX: 00005555811b5400 RCX: 00007fa1c31b3437
RDX: 0000000000000005 RSI: 0000000000000000 RDI: 0000000000000003
RBP: 00007fa1c31ec0fe R08: 0000000000000026 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000202 R12: 00005555811b7770
R13: 0000000000000026 R14: 00007ffce5a2aca0 R15: 0000000000000002
 </TASK>


Tested on:

commit:         238650ef Merge tag 'powerpc-7.3-4' of git://git.kernel..
git tree:       upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=143de115580000
kernel config:  https://syzkaller.appspot.com/x/.config?x=8c5c3949d762a91f
dashboard link: https://syzkaller.appspot.com/bug?extid=7cab6a19619f1b8efc00
compiler:       gcc (Debian 14.2.0-19) 14.2.0, GNU ld (GNU Binutils for Debian) 2.44
patch:          https://syzkaller.appspot.com/x/patch.diff?x=17ade115580000


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [syzbot] [fs?] possible deadlock in ovl_create_object (2)
  2026-09-16 21:52     ` syzbot
@ 2026-09-17  6:44       ` Chris Roy
  2026-09-17  6:59         ` syzbot
  2026-09-17  7:33         ` Greg KH
  0 siblings, 2 replies; 10+ messages in thread
From: Chris Roy @ 2026-09-17  6:44 UTC (permalink / raw)
  To: syzbot
  Cc: dakr, driver-core, gregkh, linux-fsdevel, linux-kernel, rafael,
	syzkaller-bugs

[-- Attachment #1: Type: text/plain, Size: 4750 bytes --]

On Wed, 9 Sep 2026 08:19:24 -0700, syzbot wrote:
> syzbot found the following issue on:
> ...
> possible deadlock in ovl_create_object

Follow-up / v2.

v1 deferred the open with schedule_work() and an on-stack work_struct.
That cleared the lockdep cycle, but syzbot reported an ODEBUG warning
under CONFIG_DEBUG_OBJECTS_WORK.

v2 uses a dedicated ordered workqueue and heap-allocated work, keeps a
module reference across the deferred open, flushes the queue before
exit, and serializes setup on the worker under a local mutex.

Local testing with the C reproducer (LOCKDEP + DEBUG_OBJECTS_WORK):
unpatched hits the circular locking warning; v2 is clean.

#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
master

Please consider the patch for linux-mtd.

On Thu, 17 Sept 2026 at 03:22, syzbot
<syzbot+7cab6a19619f1b8efc00@syzkaller.appspotmail.com> wrote:
>
> Hello,
>
> syzbot has tested the proposed patch but the reproducer is still triggering an issue:
> WARNING: ODEBUG bug in lookup_object_or_alloc
>
> ODEBUG: object ffffc90007cdf850 is on stack ffffc90007cd8000, but NOT annotated.
> ------------[ cut here ]------------
> 1
> WARNING: lib/debugobjects.c:672 at debug_object_is_on_stack lib/debugobjects.c:672 [inline], CPU#0: syz-executor162/6029
> WARNING: lib/debugobjects.c:672 at lookup_object_or_alloc.part.0.cold+0x19/0x40 lib/debugobjects.c:705, CPU#0: syz-executor162/6029
> Modules linked in:
> CPU: 0 UID: 0 PID: 6029 Comm: syz-executor162 Not tainted syzkaller #0 PREEMPT(full)
> Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
> RIP: 0010:debug_object_is_on_stack lib/debugobjects.c:672 [inline]
> RIP: 0010:lookup_object_or_alloc.part.0.cold+0x19/0x40 lib/debugobjects.c:705
> Code: c4 60 5b 5d 41 5c 41 5d 41 5e 41 5f c3 cc cc cc cc 83 c5 01 89 2d a0 1f 7d 1a 4c 89 e6 48 c7 c7 c0 39 62 8c e8 21 ae eb ff 90 <0f> 0b 90 e9 82 31 fe 03 83 c5 01 89 2d 7f 1f 7d 1a 49 39 c4 73 da
> RSP: 0018:ffffc90007cdf6c0 EFLAGS: 00010082
> RAX: 0000000000000050 RBX: ffff88802cb1d738 RCX: 0000000000000000
> RDX: 0000000000000050 RSI: ffffffff81ea1339 RDI: fffff52000f9bec9
> RBP: 0000000000000001 R08: 0000000000000007 R09: 0000000000000000
> R10: 8000000000000001 R11: 0000000000000001 R12: ffffc90007cdf850
> R13: ffff888034204b00 R14: 0000000000000000 R15: 0000000000000000
> FS:  00005555811b5400(0000) GS:ffff8880d5b57000(0000) knlGS:0000000000000000
> CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 00005555811b8778 CR3: 000000002bbd8000 CR4: 0000000000352ef0
> Call Trace:
>  <TASK>
>  lookup_object_or_alloc lib/debugobjects.c:682 [inline]
>  __debug_object_init+0x2a9/0x3d0 lib/debugobjects.c:798
>  __init_work+0x51/0x60 kernel/workqueue.c:697
>  block2mtd_setup_defer+0xd7/0x1d0 drivers/mtd/devices/block2mtd.c:504
>  block2mtd_setup+0x9c/0x1e0 drivers/mtd/devices/block2mtd.c:529
>  param_attr_store+0x199/0x300 kernel/params.c:591
>  module_attr_store+0x58/0x80 kernel/params.c:906
>  sysfs_kf_write+0xf2/0x150 fs/sysfs/file.c:145
>  kernfs_fop_write_iter+0x3e0/0x5f0 fs/kernfs/file.c:345
>  iter_file_splice_write+0x830/0x10b0 fs/splice.c:736
>  do_splice_from fs/splice.c:936 [inline]
>  do_splice+0x109c/0x1fa0 fs/splice.c:1349
>  __do_splice+0x33b/0x370 fs/splice.c:1431
>  __do_sys_splice fs/splice.c:1634 [inline]
>  __se_sys_splice fs/splice.c:1616 [inline]
>  __x64_sys_splice+0x187/0x250 fs/splice.c:1616
>  do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
>  do_syscall_64+0x123/0x790 arch/x86/entry/syscall_64.c:84
>  entry_SYSCALL_64_after_hwframe+0x77/0x7f
> RIP: 0033:0x7fa1c31b3437
> Code: 48 89 fa 4c 89 df e8 98 1d 00 00 8b 93 08 03 00 00 59 5e 48 83 f8 fc 74 1a 5b c3 0f 1f 84 00 00 00 00 00 48 8b 44 24 10 0f 05 <5b> c3 0f 1f 80 00 00 00 00 83 e2 39 83 fa 08 75 de e8 23 ff ff ff
> RSP: 002b:00007ffce5a2ac20 EFLAGS: 00000202 ORIG_RAX: 0000000000000113
> RAX: ffffffffffffffda RBX: 00005555811b5400 RCX: 00007fa1c31b3437
> RDX: 0000000000000005 RSI: 0000000000000000 RDI: 0000000000000003
> RBP: 00007fa1c31ec0fe R08: 0000000000000026 R09: 0000000000000000
> R10: 0000000000000000 R11: 0000000000000202 R12: 00005555811b7770
> R13: 0000000000000026 R14: 00007ffce5a2aca0 R15: 0000000000000002
>  </TASK>
>
>
> Tested on:
>
> commit:         238650ef Merge tag 'powerpc-7.3-4' of git://git.kernel..
> git tree:       upstream
> console output: https://syzkaller.appspot.com/x/log.txt?x=143de115580000
> kernel config:  https://syzkaller.appspot.com/x/.config?x=8c5c3949d762a91f
> dashboard link: https://syzkaller.appspot.com/bug?extid=7cab6a19619f1b8efc00
> compiler:       gcc (Debian 14.2.0-19) 14.2.0, GNU ld (GNU Binutils for Debian) 2.44
> patch:          https://syzkaller.appspot.com/x/patch.diff?x=17ade115580000
>

[-- Attachment #2: 0001-mtd-block2mtd-defer-device-open-out-of-param-sysfs-w.patch --]
[-- Type: text/x-diff, Size: 6392 bytes --]

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Chris Roy <iam@thechris.in>
Date: Thu, 17 Sep 2026 00:00:00 +0000
Subject: [PATCH v2] mtd: block2mtd: defer device open out of param/sysfs write

block2mtd_setup() opens the named block device (VFS path walk) while
still under param_lock and kernfs_fop_write_iter. When that write
arrives via splice, a pipe mutex is held as well. That nests under
locks already ordered the other way with overlay sb_writers /
ovl_i_mutex and triggers lockdep, for example:

  sb_writers -> pipe -> kernfs/param -> ovl_i_mutex -> sb_writers

Drop param_lock and run setup on a dedicated ordered workqueue so the
open is not nested under that stack. Keep the call synchronous with
wait_for_completion().

Changes since v1:
- allocate work on the heap (v1 tripped DEBUG_OBJECTS_WORK)
- use a dedicated ordered workqueue instead of system_wq
- hold a module reference across the deferred open
- flush and destroy the workqueue before exit teardown
- serialize setup2 on the worker under block2mtd_mutex
- keep early-boot paramline updates under that mutex

Reported-by: syzbot+7cab6a19619f1b8efc00@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=7cab6a19619f1b8efc00
Signed-off-by: Chris Roy <iam@thechris.in>
---
 drivers/mtd/devices/block2mtd.c | 121 ++++++++++++++++++++----
 1 file changed, 103 insertions(+), 18 deletions(-)

--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -27,6 +27,8 @@
 #include <linux/init.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mutex.h>
+#include <linux/workqueue.h>
+#include <linux/completion.h>
 #include <linux/mount.h>
 #include <linux/slab.h>
 #include <linux/major.h>
@@ -45,6 +47,13 @@
 
 /* Static info about the MTD, used in cleanup_module */
 static LIST_HEAD(blkmtd_device_list);
+/*
+ * Serializes setup/teardown (including list updates). Never held by a
+ * task that also holds param_lock / kernfs / pipe locks across a VFS open:
+ * deferred setup runs on block2mtd_wq instead.
+ */
+static DEFINE_MUTEX(block2mtd_mutex);
+static struct workqueue_struct *block2mtd_wq;
 
 
 static struct page *page_read(struct address_space *mapping, pgoff_t index)
@@ -461,31 +470,101 @@
 	return 0;
 }
 
+struct block2mtd_setup_work {
+	struct work_struct work;
+	struct completion done;
+	char *val;
+	int ret;
+};
+
+static void block2mtd_setup_workfn(struct work_struct *work)
+{
+	struct block2mtd_setup_work *w =
+		container_of(work, struct block2mtd_setup_work, work);
+
+	mutex_lock(&block2mtd_mutex);
+	w->ret = block2mtd_setup2(w->val);
+	mutex_unlock(&block2mtd_mutex);
+	complete(&w->done);
+}
+
+/*
+ * Run device setup on block2mtd_wq so the VFS open is not nested under
+ * param_lock, the kernfs write inode mutex, or a splice pipe lock.
+ * Work is heap-allocated (not on-stack) for CONFIG_DEBUG_OBJECTS_WORK.
+ * Caller must hold a module reference until this returns.
+ */
+static int block2mtd_setup_defer(const char *val)
+{
+	struct block2mtd_setup_work *w;
+	int ret;
+
+	if (!block2mtd_wq)
+		return -ENODEV;
+
+	w = kzalloc(sizeof(*w), GFP_KERNEL);
+	if (!w)
+		return -ENOMEM;
+
+	w->val = kstrdup(val, GFP_KERNEL);
+	if (!w->val) {
+		kfree(w);
+		return -ENOMEM;
+	}
+
+	init_completion(&w->done);
+	INIT_WORK(&w->work, block2mtd_setup_workfn);
+	queue_work(block2mtd_wq, &w->work);
+	wait_for_completion(&w->done);
+
+	ret = w->ret;
+	kfree(w->val);
+	kfree(w);
+	return ret;
+}
 
 static int block2mtd_setup(const char *val, const struct kernel_param *kp)
 {
-#ifdef MODULE
-	return block2mtd_setup2(val);
-#else
-	/* If more parameters are later passed in via
-	   /sys/module/block2mtd/parameters/block2mtd
-	   and block2mtd_init() has already been called,
-	   we can parse the argument now. */
-
-	if (block2mtd_init_called)
-		return block2mtd_setup2(val);
-
-	/* During early boot stage, we only save the parameters
-	   here. We must parse them later: if the param passed
-	   from kernel boot command line, block2mtd_setup() is
-	   called so early that it is not possible to resolve
-	   the device (even kmalloc() fails). Deter that work to
-	   block2mtd_setup2(). */
+	int ret = 0;
 
-	strscpy(block2mtd_paramline, val, sizeof(block2mtd_paramline));
+	if (!try_module_get(kp->mod))
+		return -ENODEV;
 
-	return 0;
+	/*
+	 * Leave param_lock before any path that may open a block device.
+	 * Sysfs/splice locks are still held here, so after init we must
+	 * bounce to block2mtd_wq rather than calling setup2 in-task.
+	 */
+	kernel_param_unlock(kp->mod);
+
+#ifndef MODULE
+	mutex_lock(&block2mtd_mutex);
+	if (!block2mtd_init_called) {
+		/* Early boot: cannot resolve block devices yet. */
+		strscpy(block2mtd_paramline, val, sizeof(block2mtd_paramline));
+		mutex_unlock(&block2mtd_mutex);
+		kernel_param_lock(kp->mod);
+		module_put(kp->mod);
+		return 0;
+	}
+	mutex_unlock(&block2mtd_mutex);
 #endif
+
+	if (block2mtd_wq) {
+		ret = block2mtd_setup_defer(val);
+	} else {
+		/*
+		 * Module parameter applied before module_init (insmod
+		 * args): no sysfs/splice nesting on this path.
+		 */
+		mutex_lock(&block2mtd_mutex);
+		ret = block2mtd_setup2(val);
+		mutex_unlock(&block2mtd_mutex);
+	}
+
+	kernel_param_lock(kp->mod);
+	module_put(kp->mod);
+	return ret;
 }
 
 
@@ -496,10 +575,20 @@
 {
 	int ret = 0;
 
+	block2mtd_wq = alloc_ordered_workqueue("block2mtd", 0);
+	if (!block2mtd_wq)
+		return -ENOMEM;
+
 #ifndef MODULE
+	mutex_lock(&block2mtd_mutex);
 	if (strlen(block2mtd_paramline))
 		ret = block2mtd_setup2(block2mtd_paramline);
+	/*
+	 * Publish after early paramline is consumed so a concurrent
+	 * sysfs write cannot race the buffer vs init_called.
+	 */
 	block2mtd_init_called = 1;
+	mutex_unlock(&block2mtd_mutex);
 #endif
 
 	return ret;
@@ -510,9 +599,16 @@
 {
 	struct list_head *pos, *next;
 
-	/* Remove the MTD devices */
+	if (block2mtd_wq) {
+		flush_workqueue(block2mtd_wq);
+		destroy_workqueue(block2mtd_wq);
+		block2mtd_wq = NULL;
+	}
+
+	mutex_lock(&block2mtd_mutex);
 	list_for_each_safe(pos, next, &blkmtd_device_list) {
 		struct block2mtd_dev *dev = list_entry(pos, typeof(*dev), list);
+
 		block2mtd_sync(&dev->mtd);
 		mtd_device_unregister(&dev->mtd);
 		mutex_destroy(&dev->write_mutex);
@@ -522,6 +618,7 @@
 		list_del(&dev->list);
 		block2mtd_free_device(dev);
 	}
+	mutex_unlock(&block2mtd_mutex);
 }
 
 late_initcall(block2mtd_init);

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [syzbot] [fs?] possible deadlock in ovl_create_object (2)
  2026-09-17  6:44       ` Chris Roy
@ 2026-09-17  6:59         ` syzbot
  2026-09-17  7:33         ` Greg KH
  1 sibling, 0 replies; 10+ messages in thread
From: syzbot @ 2026-09-17  6:59 UTC (permalink / raw)
  To: dakr, driver-core, gregkh, iam, linux-fsdevel, linux-kernel,
	rafael, syzkaller-bugs

Hello,

syzbot has tested the proposed patch and the reproducer did not trigger any issue:

Reported-by: syzbot+7cab6a19619f1b8efc00@syzkaller.appspotmail.com
Tested-by: syzbot+7cab6a19619f1b8efc00@syzkaller.appspotmail.com

Tested on:

commit:         238650ef Merge tag 'powerpc-7.3-4' of git://git.kernel..
git tree:       upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=13824915580000
kernel config:  https://syzkaller.appspot.com/x/.config?x=8c5c3949d762a91f
dashboard link: https://syzkaller.appspot.com/bug?extid=7cab6a19619f1b8efc00
compiler:       gcc (Debian 14.2.0-19) 14.2.0, GNU ld (GNU Binutils for Debian) 2.44
patch:          https://syzkaller.appspot.com/x/patch.diff?x=1493b925580000

Note: testing is done by a robot and is best-effort only.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [syzbot] [fs?] possible deadlock in ovl_create_object (2)
  2026-09-17  6:44       ` Chris Roy
  2026-09-17  6:59         ` syzbot
@ 2026-09-17  7:33         ` Greg KH
  2026-09-17  7:58           ` Chris Roy
  1 sibling, 1 reply; 10+ messages in thread
From: Greg KH @ 2026-09-17  7:33 UTC (permalink / raw)
  To: Chris Roy
  Cc: syzbot, dakr, driver-core, linux-fsdevel, linux-kernel, rafael,
	syzkaller-bugs

On Thu, Sep 17, 2026 at 12:14:05PM +0530, Chris Roy wrote:
> On Wed, 9 Sep 2026 08:19:24 -0700, syzbot wrote:
> > syzbot found the following issue on:
> > ...
> > possible deadlock in ovl_create_object
> 
> Follow-up / v2.
> 
> v1 deferred the open with schedule_work() and an on-stack work_struct.
> That cleared the lockdep cycle, but syzbot reported an ODEBUG warning
> under CONFIG_DEBUG_OBJECTS_WORK.
> 
> v2 uses a dedicated ordered workqueue and heap-allocated work, keeps a
> module reference across the deferred open, flushes the queue before
> exit, and serializes setup on the worker under a local mutex.
> 
> Local testing with the C reproducer (LOCKDEP + DEBUG_OBJECTS_WORK):
> unpatched hits the circular locking warning; v2 is clean.
> 
> #syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
> master
> 
> Please consider the patch for linux-mtd.
> 
> On Thu, 17 Sept 2026 at 03:22, syzbot
> <syzbot+7cab6a19619f1b8efc00@syzkaller.appspotmail.com> wrote:
> >
> > Hello,
> >
> > syzbot has tested the proposed patch but the reproducer is still triggering an issue:
> > WARNING: ODEBUG bug in lookup_object_or_alloc
> >
> > ODEBUG: object ffffc90007cdf850 is on stack ffffc90007cd8000, but NOT annotated.
> > ------------[ cut here ]------------
> > 1
> > WARNING: lib/debugobjects.c:672 at debug_object_is_on_stack lib/debugobjects.c:672 [inline], CPU#0: syz-executor162/6029
> > WARNING: lib/debugobjects.c:672 at lookup_object_or_alloc.part.0.cold+0x19/0x40 lib/debugobjects.c:705, CPU#0: syz-executor162/6029
> > Modules linked in:
> > CPU: 0 UID: 0 PID: 6029 Comm: syz-executor162 Not tainted syzkaller #0 PREEMPT(full)
> > Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
> > RIP: 0010:debug_object_is_on_stack lib/debugobjects.c:672 [inline]
> > RIP: 0010:lookup_object_or_alloc.part.0.cold+0x19/0x40 lib/debugobjects.c:705
> > Code: c4 60 5b 5d 41 5c 41 5d 41 5e 41 5f c3 cc cc cc cc 83 c5 01 89 2d a0 1f 7d 1a 4c 89 e6 48 c7 c7 c0 39 62 8c e8 21 ae eb ff 90 <0f> 0b 90 e9 82 31 fe 03 83 c5 01 89 2d 7f 1f 7d 1a 49 39 c4 73 da
> > RSP: 0018:ffffc90007cdf6c0 EFLAGS: 00010082
> > RAX: 0000000000000050 RBX: ffff88802cb1d738 RCX: 0000000000000000
> > RDX: 0000000000000050 RSI: ffffffff81ea1339 RDI: fffff52000f9bec9
> > RBP: 0000000000000001 R08: 0000000000000007 R09: 0000000000000000
> > R10: 8000000000000001 R11: 0000000000000001 R12: ffffc90007cdf850
> > R13: ffff888034204b00 R14: 0000000000000000 R15: 0000000000000000
> > FS:  00005555811b5400(0000) GS:ffff8880d5b57000(0000) knlGS:0000000000000000
> > CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> > CR2: 00005555811b8778 CR3: 000000002bbd8000 CR4: 0000000000352ef0
> > Call Trace:
> >  <TASK>
> >  lookup_object_or_alloc lib/debugobjects.c:682 [inline]
> >  __debug_object_init+0x2a9/0x3d0 lib/debugobjects.c:798
> >  __init_work+0x51/0x60 kernel/workqueue.c:697
> >  block2mtd_setup_defer+0xd7/0x1d0 drivers/mtd/devices/block2mtd.c:504
> >  block2mtd_setup+0x9c/0x1e0 drivers/mtd/devices/block2mtd.c:529
> >  param_attr_store+0x199/0x300 kernel/params.c:591
> >  module_attr_store+0x58/0x80 kernel/params.c:906
> >  sysfs_kf_write+0xf2/0x150 fs/sysfs/file.c:145
> >  kernfs_fop_write_iter+0x3e0/0x5f0 fs/kernfs/file.c:345
> >  iter_file_splice_write+0x830/0x10b0 fs/splice.c:736
> >  do_splice_from fs/splice.c:936 [inline]
> >  do_splice+0x109c/0x1fa0 fs/splice.c:1349
> >  __do_splice+0x33b/0x370 fs/splice.c:1431
> >  __do_sys_splice fs/splice.c:1634 [inline]
> >  __se_sys_splice fs/splice.c:1616 [inline]
> >  __x64_sys_splice+0x187/0x250 fs/splice.c:1616
> >  do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
> >  do_syscall_64+0x123/0x790 arch/x86/entry/syscall_64.c:84
> >  entry_SYSCALL_64_after_hwframe+0x77/0x7f
> > RIP: 0033:0x7fa1c31b3437
> > Code: 48 89 fa 4c 89 df e8 98 1d 00 00 8b 93 08 03 00 00 59 5e 48 83 f8 fc 74 1a 5b c3 0f 1f 84 00 00 00 00 00 48 8b 44 24 10 0f 05 <5b> c3 0f 1f 80 00 00 00 00 83 e2 39 83 fa 08 75 de e8 23 ff ff ff
> > RSP: 002b:00007ffce5a2ac20 EFLAGS: 00000202 ORIG_RAX: 0000000000000113
> > RAX: ffffffffffffffda RBX: 00005555811b5400 RCX: 00007fa1c31b3437
> > RDX: 0000000000000005 RSI: 0000000000000000 RDI: 0000000000000003
> > RBP: 00007fa1c31ec0fe R08: 0000000000000026 R09: 0000000000000000
> > R10: 0000000000000000 R11: 0000000000000202 R12: 00005555811b7770
> > R13: 0000000000000026 R14: 00007ffce5a2aca0 R15: 0000000000000002
> >  </TASK>
> >
> >
> > Tested on:
> >
> > commit:         238650ef Merge tag 'powerpc-7.3-4' of git://git.kernel..
> > git tree:       upstream
> > console output: https://syzkaller.appspot.com/x/log.txt?x=143de115580000
> > kernel config:  https://syzkaller.appspot.com/x/.config?x=8c5c3949d762a91f
> > dashboard link: https://syzkaller.appspot.com/bug?extid=7cab6a19619f1b8efc00
> > compiler:       gcc (Debian 14.2.0-19) 14.2.0, GNU ld (GNU Binutils for Debian) 2.44
> > patch:          https://syzkaller.appspot.com/x/patch.diff?x=17ade115580000
> >

> From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
> From: Chris Roy <iam@thechris.in>
> Date: Thu, 17 Sep 2026 00:00:00 +0000
> Subject: [PATCH v2] mtd: block2mtd: defer device open out of param/sysfs write
> 
> block2mtd_setup() opens the named block device (VFS path walk) while
> still under param_lock and kernfs_fop_write_iter. When that write
> arrives via splice, a pipe mutex is held as well. That nests under
> locks already ordered the other way with overlay sb_writers /
> ovl_i_mutex and triggers lockdep, for example:
> 
>   sb_writers -> pipe -> kernfs/param -> ovl_i_mutex -> sb_writers
> 
> Drop param_lock and run setup on a dedicated ordered workqueue so the
> open is not nested under that stack. Keep the call synchronous with
> wait_for_completion().
> 
> Changes since v1:
> - allocate work on the heap (v1 tripped DEBUG_OBJECTS_WORK)
> - use a dedicated ordered workqueue instead of system_wq
> - hold a module reference across the deferred open
> - flush and destroy the workqueue before exit teardown
> - serialize setup2 on the worker under block2mtd_mutex
> - keep early-boot paramline updates under that mutex
> 
> Reported-by: syzbot+7cab6a19619f1b8efc00@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=7cab6a19619f1b8efc00
> Signed-off-by: Chris Roy <iam@thechris.in>
> ---
>  drivers/mtd/devices/block2mtd.c | 121 ++++++++++++++++++++----
>  1 file changed, 103 insertions(+), 18 deletions(-)

Did you forget the Assisted-by: tag?

> 
> --- a/drivers/mtd/devices/block2mtd.c
> +++ b/drivers/mtd/devices/block2mtd.c
> @@ -27,6 +27,8 @@
>  #include <linux/init.h>
>  #include <linux/mtd/mtd.h>
>  #include <linux/mutex.h>
> +#include <linux/workqueue.h>
> +#include <linux/completion.h>
>  #include <linux/mount.h>
>  #include <linux/slab.h>
>  #include <linux/major.h>
> @@ -45,6 +47,13 @@
>  
>  /* Static info about the MTD, used in cleanup_module */
>  static LIST_HEAD(blkmtd_device_list);
> +/*
> + * Serializes setup/teardown (including list updates). Never held by a
> + * task that also holds param_lock / kernfs / pipe locks across a VFS open:
> + * deferred setup runs on block2mtd_wq instead.

Make the comments make sense please.  That's the problem of using a LLM :(

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [syzbot] [fs?] possible deadlock in ovl_create_object (2)
  2026-09-17  7:33         ` Greg KH
@ 2026-09-17  7:58           ` Chris Roy
  2026-09-17  8:13             ` syzbot
  0 siblings, 1 reply; 10+ messages in thread
From: Chris Roy @ 2026-09-17  7:58 UTC (permalink / raw)
  To: Greg KH
  Cc: syzbot, dakr, driver-core, linux-fsdevel, linux-kernel, rafael,
	syzkaller-bugs, linux-mtd, miquel.raynal, richard, vigneshr,
	joern

[-- Attachment #1: Type: text/plain, Size: 8056 bytes --]

On Thu, Sep 17, 2026 at 13:05:00 +0530, Greg KH wrote:
> Did you forget the Assisted-by: tag?
>
> Make the comments make sense please. That's the problem of using a LLM :(

Fair. v3 adds Assisted-by and rewrites those comments.
Same approach as v2 otherwise. syzbot tested v2 cleanly on this bug.

#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
master

Please consider for linux-mtd.

On Thu, 17 Sept 2026 at 13:05, Greg KH <gregkh@linuxfoundation.org> wrote:
>
> On Thu, Sep 17, 2026 at 12:14:05PM +0530, Chris Roy wrote:
> > On Wed, 9 Sep 2026 08:19:24 -0700, syzbot wrote:
> > > syzbot found the following issue on:
> > > ...
> > > possible deadlock in ovl_create_object
> >
> > Follow-up / v2.
> >
> > v1 deferred the open with schedule_work() and an on-stack work_struct.
> > That cleared the lockdep cycle, but syzbot reported an ODEBUG warning
> > under CONFIG_DEBUG_OBJECTS_WORK.
> >
> > v2 uses a dedicated ordered workqueue and heap-allocated work, keeps a
> > module reference across the deferred open, flushes the queue before
> > exit, and serializes setup on the worker under a local mutex.
> >
> > Local testing with the C reproducer (LOCKDEP + DEBUG_OBJECTS_WORK):
> > unpatched hits the circular locking warning; v2 is clean.
> >
> > #syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
> > master
> >
> > Please consider the patch for linux-mtd.
> >
> > On Thu, 17 Sept 2026 at 03:22, syzbot
> > <syzbot+7cab6a19619f1b8efc00@syzkaller.appspotmail.com> wrote:
> > >
> > > Hello,
> > >
> > > syzbot has tested the proposed patch but the reproducer is still triggering an issue:
> > > WARNING: ODEBUG bug in lookup_object_or_alloc
> > >
> > > ODEBUG: object ffffc90007cdf850 is on stack ffffc90007cd8000, but NOT annotated.
> > > ------------[ cut here ]------------
> > > 1
> > > WARNING: lib/debugobjects.c:672 at debug_object_is_on_stack lib/debugobjects.c:672 [inline], CPU#0: syz-executor162/6029
> > > WARNING: lib/debugobjects.c:672 at lookup_object_or_alloc.part.0.cold+0x19/0x40 lib/debugobjects.c:705, CPU#0: syz-executor162/6029
> > > Modules linked in:
> > > CPU: 0 UID: 0 PID: 6029 Comm: syz-executor162 Not tainted syzkaller #0 PREEMPT(full)
> > > Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
> > > RIP: 0010:debug_object_is_on_stack lib/debugobjects.c:672 [inline]
> > > RIP: 0010:lookup_object_or_alloc.part.0.cold+0x19/0x40 lib/debugobjects.c:705
> > > Code: c4 60 5b 5d 41 5c 41 5d 41 5e 41 5f c3 cc cc cc cc 83 c5 01 89 2d a0 1f 7d 1a 4c 89 e6 48 c7 c7 c0 39 62 8c e8 21 ae eb ff 90 <0f> 0b 90 e9 82 31 fe 03 83 c5 01 89 2d 7f 1f 7d 1a 49 39 c4 73 da
> > > RSP: 0018:ffffc90007cdf6c0 EFLAGS: 00010082
> > > RAX: 0000000000000050 RBX: ffff88802cb1d738 RCX: 0000000000000000
> > > RDX: 0000000000000050 RSI: ffffffff81ea1339 RDI: fffff52000f9bec9
> > > RBP: 0000000000000001 R08: 0000000000000007 R09: 0000000000000000
> > > R10: 8000000000000001 R11: 0000000000000001 R12: ffffc90007cdf850
> > > R13: ffff888034204b00 R14: 0000000000000000 R15: 0000000000000000
> > > FS:  00005555811b5400(0000) GS:ffff8880d5b57000(0000) knlGS:0000000000000000
> > > CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> > > CR2: 00005555811b8778 CR3: 000000002bbd8000 CR4: 0000000000352ef0
> > > Call Trace:
> > >  <TASK>
> > >  lookup_object_or_alloc lib/debugobjects.c:682 [inline]
> > >  __debug_object_init+0x2a9/0x3d0 lib/debugobjects.c:798
> > >  __init_work+0x51/0x60 kernel/workqueue.c:697
> > >  block2mtd_setup_defer+0xd7/0x1d0 drivers/mtd/devices/block2mtd.c:504
> > >  block2mtd_setup+0x9c/0x1e0 drivers/mtd/devices/block2mtd.c:529
> > >  param_attr_store+0x199/0x300 kernel/params.c:591
> > >  module_attr_store+0x58/0x80 kernel/params.c:906
> > >  sysfs_kf_write+0xf2/0x150 fs/sysfs/file.c:145
> > >  kernfs_fop_write_iter+0x3e0/0x5f0 fs/kernfs/file.c:345
> > >  iter_file_splice_write+0x830/0x10b0 fs/splice.c:736
> > >  do_splice_from fs/splice.c:936 [inline]
> > >  do_splice+0x109c/0x1fa0 fs/splice.c:1349
> > >  __do_splice+0x33b/0x370 fs/splice.c:1431
> > >  __do_sys_splice fs/splice.c:1634 [inline]
> > >  __se_sys_splice fs/splice.c:1616 [inline]
> > >  __x64_sys_splice+0x187/0x250 fs/splice.c:1616
> > >  do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
> > >  do_syscall_64+0x123/0x790 arch/x86/entry/syscall_64.c:84
> > >  entry_SYSCALL_64_after_hwframe+0x77/0x7f
> > > RIP: 0033:0x7fa1c31b3437
> > > Code: 48 89 fa 4c 89 df e8 98 1d 00 00 8b 93 08 03 00 00 59 5e 48 83 f8 fc 74 1a 5b c3 0f 1f 84 00 00 00 00 00 48 8b 44 24 10 0f 05 <5b> c3 0f 1f 80 00 00 00 00 83 e2 39 83 fa 08 75 de e8 23 ff ff ff
> > > RSP: 002b:00007ffce5a2ac20 EFLAGS: 00000202 ORIG_RAX: 0000000000000113
> > > RAX: ffffffffffffffda RBX: 00005555811b5400 RCX: 00007fa1c31b3437
> > > RDX: 0000000000000005 RSI: 0000000000000000 RDI: 0000000000000003
> > > RBP: 00007fa1c31ec0fe R08: 0000000000000026 R09: 0000000000000000
> > > R10: 0000000000000000 R11: 0000000000000202 R12: 00005555811b7770
> > > R13: 0000000000000026 R14: 00007ffce5a2aca0 R15: 0000000000000002
> > >  </TASK>
> > >
> > >
> > > Tested on:
> > >
> > > commit:         238650ef Merge tag 'powerpc-7.3-4' of git://git.kernel..
> > > git tree:       upstream
> > > console output: https://syzkaller.appspot.com/x/log.txt?x=143de115580000
> > > kernel config:  https://syzkaller.appspot.com/x/.config?x=8c5c3949d762a91f
> > > dashboard link: https://syzkaller.appspot.com/bug?extid=7cab6a19619f1b8efc00
> > > compiler:       gcc (Debian 14.2.0-19) 14.2.0, GNU ld (GNU Binutils for Debian) 2.44
> > > patch:          https://syzkaller.appspot.com/x/patch.diff?x=17ade115580000
> > >
>
> > From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
> > From: Chris Roy <iam@thechris.in>
> > Date: Thu, 17 Sep 2026 00:00:00 +0000
> > Subject: [PATCH v2] mtd: block2mtd: defer device open out of param/sysfs write
> >
> > block2mtd_setup() opens the named block device (VFS path walk) while
> > still under param_lock and kernfs_fop_write_iter. When that write
> > arrives via splice, a pipe mutex is held as well. That nests under
> > locks already ordered the other way with overlay sb_writers /
> > ovl_i_mutex and triggers lockdep, for example:
> >
> >   sb_writers -> pipe -> kernfs/param -> ovl_i_mutex -> sb_writers
> >
> > Drop param_lock and run setup on a dedicated ordered workqueue so the
> > open is not nested under that stack. Keep the call synchronous with
> > wait_for_completion().
> >
> > Changes since v1:
> > - allocate work on the heap (v1 tripped DEBUG_OBJECTS_WORK)
> > - use a dedicated ordered workqueue instead of system_wq
> > - hold a module reference across the deferred open
> > - flush and destroy the workqueue before exit teardown
> > - serialize setup2 on the worker under block2mtd_mutex
> > - keep early-boot paramline updates under that mutex
> >
> > Reported-by: syzbot+7cab6a19619f1b8efc00@syzkaller.appspotmail.com
> > Closes: https://syzkaller.appspot.com/bug?extid=7cab6a19619f1b8efc00
> > Signed-off-by: Chris Roy <iam@thechris.in>
> > ---
> >  drivers/mtd/devices/block2mtd.c | 121 ++++++++++++++++++++----
> >  1 file changed, 103 insertions(+), 18 deletions(-)
>
> Did you forget the Assisted-by: tag?
>
> >
> > --- a/drivers/mtd/devices/block2mtd.c
> > +++ b/drivers/mtd/devices/block2mtd.c
> > @@ -27,6 +27,8 @@
> >  #include <linux/init.h>
> >  #include <linux/mtd/mtd.h>
> >  #include <linux/mutex.h>
> > +#include <linux/workqueue.h>
> > +#include <linux/completion.h>
> >  #include <linux/mount.h>
> >  #include <linux/slab.h>
> >  #include <linux/major.h>
> > @@ -45,6 +47,13 @@
> >
> >  /* Static info about the MTD, used in cleanup_module */
> >  static LIST_HEAD(blkmtd_device_list);
> > +/*
> > + * Serializes setup/teardown (including list updates). Never held by a
> > + * task that also holds param_lock / kernfs / pipe locks across a VFS open:
> > + * deferred setup runs on block2mtd_wq instead.
>
> Make the comments make sense please.  That's the problem of using a LLM :(
>
> thanks,
>
> greg k-h

[-- Attachment #2: 0001-mtd-block2mtd-defer-device-open-out-of-param-sysfs-w.patch --]
[-- Type: text/x-diff, Size: 5697 bytes --]

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Chris Roy <iam@thechris.in>
Date: Thu, 17 Sep 2026 00:00:00 +0000
Subject: [PATCH v3] mtd: block2mtd: defer device open out of param/sysfs write

block2mtd_setup() opens the named block device while still under
param_lock, and on the sysfs write path under kernfs (and possibly a
splice pipe lock). That nests VFS locking the wrong way relative to
overlayfs and trips lockdep.

Drop param_lock and run setup on a dedicated ordered workqueue. Keep
the call synchronous with wait_for_completion(). Allocate the work on
the heap so DEBUG_OBJECTS_WORK stays quiet.

Changes since v2:
- rewrite the new comments to match the rest of the file

Changes since v1:
- heap-allocated work (v1 tripped DEBUG_OBJECTS_WORK)
- dedicated ordered workqueue instead of system_wq
- module reference across the deferred open
- flush/destroy the workqueue before exit teardown
- serialize setup2 on the worker under block2mtd_mutex
- early-boot paramline updates under that mutex

Reported-by: syzbot+7cab6a19619f1b8efc00@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=7cab6a19619f1b8efc00
Assisted-by: Mistral, Qwen
Signed-off-by: Chris Roy <iam@thechris.in>
---
 drivers/mtd/devices/block2mtd.c | 118 ++++++++++++++++++++-----
 1 file changed, 98 insertions(+), 20 deletions(-)

--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -27,6 +27,8 @@
 #include <linux/init.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mutex.h>
+#include <linux/workqueue.h>
+#include <linux/completion.h>
 #include <linux/mount.h>
 #include <linux/slab.h>
 #include <linux/major.h>
@@ -45,6 +47,9 @@
 
 /* Static info about the MTD, used in cleanup_module */
 static LIST_HEAD(blkmtd_device_list);
+/* Protects blkmtd_device_list and early-boot paramline updates */
+static DEFINE_MUTEX(block2mtd_mutex);
+static struct workqueue_struct *block2mtd_wq;
 
 
 static struct page *page_read(struct address_space *mapping, pgoff_t index)
@@ -461,31 +466,89 @@
 	return 0;
 }
 
+struct block2mtd_setup_work {
+	struct work_struct work;
+	struct completion done;
+	char *val;
+	int ret;
+};
+
+static void block2mtd_setup_workfn(struct work_struct *work)
+{
+	struct block2mtd_setup_work *w =
+		container_of(work, struct block2mtd_setup_work, work);
+
+	mutex_lock(&block2mtd_mutex);
+	w->ret = block2mtd_setup2(w->val);
+	mutex_unlock(&block2mtd_mutex);
+	complete(&w->done);
+}
+
+/* Queue setup2 on block2mtd_wq; caller holds a module ref until return */
+static int block2mtd_setup_defer(const char *val)
+{
+	struct block2mtd_setup_work *w;
+	int ret;
+
+	if (!block2mtd_wq)
+		return -ENODEV;
+
+	w = kzalloc(sizeof(*w), GFP_KERNEL);
+	if (!w)
+		return -ENOMEM;
+
+	w->val = kstrdup(val, GFP_KERNEL);
+	if (!w->val) {
+		kfree(w);
+		return -ENOMEM;
+	}
+
+	init_completion(&w->done);
+	INIT_WORK(&w->work, block2mtd_setup_workfn);
+	queue_work(block2mtd_wq, &w->work);
+	wait_for_completion(&w->done);
+
+	ret = w->ret;
+	kfree(w->val);
+	kfree(w);
+	return ret;
+}
 
 static int block2mtd_setup(const char *val, const struct kernel_param *kp)
 {
-#ifdef MODULE
-	return block2mtd_setup2(val);
-#else
-	/* If more parameters are later passed in via
-	   /sys/module/block2mtd/parameters/block2mtd
-	   and block2mtd_init() has already been called,
-	   we can parse the argument now. */
-
-	if (block2mtd_init_called)
-		return block2mtd_setup2(val);
-
-	/* During early boot stage, we only save the parameters
-	   here. We must parse them later: if the param passed
-	   from kernel boot command line, block2mtd_setup() is
-	   called so early that it is not possible to resolve
-	   the device (even kmalloc() fails). Deter that work to
-	   block2mtd_setup2(). */
+	int ret = 0;
 
-	strscpy(block2mtd_paramline, val, sizeof(block2mtd_paramline));
+	if (!try_module_get(kp->mod))
+		return -ENODEV;
 
-	return 0;
+	/* Do not open a block device under param_lock */
+	kernel_param_unlock(kp->mod);
+
+#ifndef MODULE
+	mutex_lock(&block2mtd_mutex);
+	if (!block2mtd_init_called) {
+		/* Early boot: cannot resolve block devices yet. */
+		strscpy(block2mtd_paramline, val, sizeof(block2mtd_paramline));
+		mutex_unlock(&block2mtd_mutex);
+		kernel_param_lock(kp->mod);
+		module_put(kp->mod);
+		return 0;
+	}
+	mutex_unlock(&block2mtd_mutex);
 #endif
+
+	if (block2mtd_wq) {
+		ret = block2mtd_setup_defer(val);
+	} else {
+		/* Pre-init (e.g. insmod args): safe to run setup2 here */
+		mutex_lock(&block2mtd_mutex);
+		ret = block2mtd_setup2(val);
+		mutex_unlock(&block2mtd_mutex);
+	}
+
+	kernel_param_lock(kp->mod);
+	module_put(kp->mod);
+	return ret;
 }
 
 
@@ -496,10 +559,17 @@
 {
 	int ret = 0;
 
+	block2mtd_wq = alloc_ordered_workqueue("block2mtd", 0);
+	if (!block2mtd_wq)
+		return -ENOMEM;
+
 #ifndef MODULE
+	mutex_lock(&block2mtd_mutex);
 	if (strlen(block2mtd_paramline))
 		ret = block2mtd_setup2(block2mtd_paramline);
+	/* Avoid racing sysfs with the early paramline */
 	block2mtd_init_called = 1;
+	mutex_unlock(&block2mtd_mutex);
 #endif
 
 	return ret;
@@ -510,9 +580,16 @@
 {
 	struct list_head *pos, *next;
 
-	/* Remove the MTD devices */
+	if (block2mtd_wq) {
+		flush_workqueue(block2mtd_wq);
+		destroy_workqueue(block2mtd_wq);
+		block2mtd_wq = NULL;
+	}
+
+	mutex_lock(&block2mtd_mutex);
 	list_for_each_safe(pos, next, &blkmtd_device_list) {
 		struct block2mtd_dev *dev = list_entry(pos, typeof(*dev), list);
+
 		block2mtd_sync(&dev->mtd);
 		mtd_device_unregister(&dev->mtd);
 		mutex_destroy(&dev->write_mutex);
@@ -522,6 +599,7 @@
 		list_del(&dev->list);
 		block2mtd_free_device(dev);
 	}
+	mutex_unlock(&block2mtd_mutex);
 }
 
 late_initcall(block2mtd_init);

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [syzbot] [fs?] possible deadlock in ovl_create_object (2)
  2026-09-17  7:58           ` Chris Roy
@ 2026-09-17  8:13             ` syzbot
  0 siblings, 0 replies; 10+ messages in thread
From: syzbot @ 2026-09-17  8:13 UTC (permalink / raw)
  To: dakr, driver-core, gregkh, iam, joern, linux-fsdevel,
	linux-kernel, linux-mtd, miquel.raynal, rafael, richard,
	syzkaller-bugs, vigneshr

Hello,

syzbot has tested the proposed patch and the reproducer did not trigger any issue:

Reported-by: syzbot+7cab6a19619f1b8efc00@syzkaller.appspotmail.com
Tested-by: syzbot+7cab6a19619f1b8efc00@syzkaller.appspotmail.com

Tested on:

commit:         238650ef Merge tag 'powerpc-7.3-4' of git://git.kernel..
git tree:       upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=165358c9580000
kernel config:  https://syzkaller.appspot.com/x/.config?x=8c5c3949d762a91f
dashboard link: https://syzkaller.appspot.com/bug?extid=7cab6a19619f1b8efc00
compiler:       gcc (Debian 14.2.0-19) 14.2.0, GNU ld (GNU Binutils for Debian) 2.44
patch:          https://syzkaller.appspot.com/x/patch.diff?x=117a3bf9580000

Note: testing is done by a robot and is best-effort only.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2026-09-17  8:13 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-09 15:19 [syzbot] [fs?] possible deadlock in ovl_create_object (2) syzbot
2026-09-12 13:12 ` syzbot
2026-09-16 19:48 ` Chris Roy
2026-09-16 21:37   ` Chris Roy
2026-09-16 21:52     ` syzbot
2026-09-17  6:44       ` Chris Roy
2026-09-17  6:59         ` syzbot
2026-09-17  7:33         ` Greg KH
2026-09-17  7:58           ` Chris Roy
2026-09-17  8:13             ` syzbot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®