In the Linux kernel, the following vulnerability has been resolved:
netrom: fix possible dead-lock in nrrtioctl()
syzbot loves netrom, and found a possible deadlock in nrrtioctl [1]
Make sure we always acquire nrnodelistlock before nrnodelock(nrnode)
[1] WARNING: possible circular locking dependency detected
syz-executor350/5129 is trying to acquire lock: ffff8880186e2070 (&nrnode->nodelock){+...}-{2:2}, at: spinlockbh include/linux/spinlock.h:356 [inline] ffff8880186e2070 (&nrnode->nodelock){+...}-{2:2}, at: nrnodelock include/net/netrom.h:152 [inline] ffff8880186e2070 (&nrnode->nodelock){+...}-{2:2}, at: nrdecobs net/netrom/nrroute.c:464 [inline] ffff8880186e2070 (&nrnode->nodelock){+...}-{2:2}, at: nrrtioctl+0x1bb/0x1090 net/netrom/nrroute.c:697
but task is already holding lock: ffffffff8f7053b8 (nrnodelistlock){+...}-{2:2}, at: spinlockbh include/linux/spinlock.h:356 [inline] ffffffff8f7053b8 (nrnodelistlock){+...}-{2:2}, at: nrdecobs net/netrom/nrroute.c:462 [inline] ffffffff8f7053b8 (nrnodelistlock){+...}-{2:2}, at: nrrtioctl+0x10a/0x1090 net/netrom/nr_route.c:697
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (nrnodelistlock){+...}-{2:2}: lockacquire+0x1ed/0x550 kernel/locking/lockdep.c:5754 _rawspinlockbh include/linux/spinlockapismp.h:126 [inline] rawspinlockbh+0x35/0x50 kernel/locking/spinlock.c:178 spinlockbh include/linux/spinlock.h:356 [inline] nrremovenode net/netrom/nrroute.c:299 [inline] nrdelnode+0x4b4/0x820 net/netrom/nrroute.c:355 nrrtioctl+0xa95/0x1090 net/netrom/nrroute.c:683 sockdoioctl+0x158/0x460 net/socket.c:1222 sockioctl+0x629/0x8e0 net/socket.c:1341 vfsioctl fs/ioctl.c:51 [inline] _dosysioctl fs/ioctl.c:904 [inline] _sesysioctl+0xfc/0x170 fs/ioctl.c:890 dosyscallx64 arch/x86/entry/common.c:52 [inline] dosyscall64+0xf5/0x240 arch/x86/entry/common.c:83 entrySYSCALL64after_hwframe+0x77/0x7f
-> #0 (&nrnode->nodelock){+...}-{2:2}: checkprevadd kernel/locking/lockdep.c:3134 [inline] checkprevsadd kernel/locking/lockdep.c:3253 [inline] validatechain+0x18cb/0x58e0 kernel/locking/lockdep.c:3869 _lockacquire+0x1346/0x1fd0 kernel/locking/lockdep.c:5137 lockacquire+0x1ed/0x550 kernel/locking/lockdep.c:5754 _rawspinlockbh include/linux/spinlockapismp.h:126 [inline] rawspinlockbh+0x35/0x50 kernel/locking/spinlock.c:178 spinlockbh include/linux/spinlock.h:356 [inline] nrnodelock include/net/netrom.h:152 [inline] nrdecobs net/netrom/nrroute.c:464 [inline] nrrtioctl+0x1bb/0x1090 net/netrom/nrroute.c:697 sockdoioctl+0x158/0x460 net/socket.c:1222 sockioctl+0x629/0x8e0 net/socket.c:1341 vfsioctl fs/ioctl.c:51 [inline] _dosysioctl fs/ioctl.c:904 [inline] _sesysioctl+0xfc/0x170 fs/ioctl.c:890 dosyscallx64 arch/x86/entry/common.c:52 [inline] dosyscall64+0xf5/0x240 arch/x86/entry/common.c:83 entrySYSCALL64afterhwframe+0x77/0x7f
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(nrnodelistlock); lock(&nrnode->nodelock); lock(nrnodelistlock); lock(&nrnode->nodelock);
* DEADLOCK *
1 lock held by syz-executor350/5129: #0: ffffffff8f7053b8 (nrnodelistlock){+...}-{2:2}, at: spinlockbh include/linux/spinlock.h:356 [inline] #0: ffffffff8f7053b8 (nrnodelistlock){+...}-{2:2}, at: nrdecobs net/netrom/nr_route.c:462 [inline] #0: ffffffff8f70 ---truncated---