mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [Linux Kernel Bug] possible deadlock in l2cap_chan_connect
@ 2026-09-11 16:59 Jiaming Zhang
  2026-09-11 18:38 ` Ali Ahmet Memiş
  0 siblings, 1 reply; 4+ messages in thread
From: Jiaming Zhang @ 2026-09-11 16:59 UTC (permalink / raw)
  To: marcel, luiz.dentz, linux-bluetooth
  Cc: ali, kees, kuba, linux-kernel, nicoyip.dev, suunj1331, syzkaller,
	r772577952

Dear Linux kernel developers and maintainers,

We are writing to report an issue discovered in the Bluetooth subsystem.  The
issue is reproducible on the latest version of linux (v7.3-rc2, commit
df2908090cda368b01ff43709f51890076c56157).  Below is the kernel report:

======================================================
WARNING: possible circular locking dependency detected
7.3.0-rc2 #42 Not tainted
------------------------------------------------------
syz-executor108/9473 is trying to acquire lock:
ffff8880467900b8 (&hdev->lock){+.+.}-{4:4}, at:
l2cap_chan_connect+0xa0/0x1130 net/bluetooth/l2cap_core.c:7281

but task is already holding lock:
ffffffff8fdbc6c0 (rfcomm_mutex){+.+.}-{4:4}, at:
rfcomm_dlc_open+0x95/0xee0 net/bluetooth/rfcomm/core.c:426

which lock already depends on the new lock.


the existing dependency chain (in reverse order) is:

-> #2 (rfcomm_mutex){+.+.}-{4:4}:
       lock_acquire+0x116/0x350 kernel/locking/lockdep.c:5942
       __mutex_lock_common kernel/locking/mutex.c:646 [inline]
       __mutex_lock+0x184/0x1590 kernel/locking/mutex.c:821
       rfcomm_security_cfm+0x41/0x450 net/bluetooth/rfcomm/core.c:2222
       hci_encrypt_cfm+0x384/0x500 include/net/bluetooth/hci_core.h:2242
       hci_encrypt_change_evt+0x5fa/0xce0 net/bluetooth/hci_event.c:3674
       hci_event_func net/bluetooth/hci_event.c:7887 [inline]
       hci_event_packet+0x665/0xec0 net/bluetooth/hci_event.c:7938
       hci_rx_work+0x3ee/0x1070 net/bluetooth/hci_core.c:4041
       process_one_work kernel/workqueue.c:3396 [inline]
       process_scheduled_works+0xc85/0x18f0 kernel/workqueue.c:3479
       worker_thread+0x8a3/0xda0 kernel/workqueue.c:3560
       kthread+0x38c/0x480 kernel/kthread.c:436
       ret_from_fork+0x509/0xb70 arch/x86/kernel/process.c:158
       ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245

-> #1 (hci_cb_list_lock){+.+.}-{4:4}:
       lock_acquire+0x116/0x350 kernel/locking/lockdep.c:5942
       __mutex_lock_common kernel/locking/mutex.c:646 [inline]
       __mutex_lock+0x184/0x1590 kernel/locking/mutex.c:821
       hci_connect_cfm include/net/bluetooth/hci_core.h:2163 [inline]
       hci_remote_features_evt+0x51c/0x920 net/bluetooth/hci_event.c:3786
       hci_event_func net/bluetooth/hci_event.c:7887 [inline]
       hci_event_packet+0x665/0xec0 net/bluetooth/hci_event.c:7938
       hci_rx_work+0x3ee/0x1070 net/bluetooth/hci_core.c:4041
       process_one_work kernel/workqueue.c:3396 [inline]
       process_scheduled_works+0xc85/0x18f0 kernel/workqueue.c:3479
       worker_thread+0x8a3/0xda0 kernel/workqueue.c:3560
       kthread+0x38c/0x480 kernel/kthread.c:436
       ret_from_fork+0x509/0xb70 arch/x86/kernel/process.c:158
       ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245

-> #0 (&hdev->lock){+.+.}-{4:4}:
       check_prev_add kernel/locking/lockdep.c:3209 [inline]
       check_prevs_add kernel/locking/lockdep.c:3328 [inline]
       validate_chain+0xa41/0x2560 kernel/locking/lockdep.c:3952
       __lock_acquire+0xbe0/0xf10 kernel/locking/lockdep.c:5288
       lock_acquire+0x116/0x350 kernel/locking/lockdep.c:5942
       __mutex_lock_common kernel/locking/mutex.c:646 [inline]
       __mutex_lock+0x184/0x1590 kernel/locking/mutex.c:821
       l2cap_chan_connect+0xa0/0x1130 net/bluetooth/l2cap_core.c:7281
       l2cap_sock_connect+0x5c8/0x7d0 net/bluetooth/l2cap_sock.c:255
       kernel_connect+0x116/0x180 net/socket.c:3755
       rfcomm_session_create net/bluetooth/rfcomm/core.c:808 [inline]
       __rfcomm_dlc_open net/bluetooth/rfcomm/core.c:385 [inline]
       rfcomm_dlc_open+0x924/0xee0 net/bluetooth/rfcomm/core.c:428
       rfcomm_sock_connect+0x2f7/0x650 net/bluetooth/rfcomm/sock.c:421
       connect_socket net/socket.c:2141 [inline]
       __sys_connect_file net/socket.c:2166 [inline]
       __sys_connect+0x30e/0x430 net/socket.c:2183
       __do_sys_connect net/socket.c:2189 [inline]
       __se_sys_connect net/socket.c:2186 [inline]
       __x64_sys_connect+0x7a/0x90 net/socket.c:2186
       do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
       do_syscall_64+0x170/0x540 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:
  &hdev->lock --> hci_cb_list_lock --> rfcomm_mutex

 Possible unsafe locking scenario:

       CPU0                    CPU1
       ----                    ----
  lock(rfcomm_mutex);
                               lock(hci_cb_list_lock);
                               lock(rfcomm_mutex);
  lock(&hdev->lock);

 *** DEADLOCK ***

locks held by syz-executor108/9473: 1, last CPU#0:
 #0: ffffffff8fdbc6c0 (rfcomm_mutex){+.+.}-{4:4}, at:
rfcomm_dlc_open+0x95/0xee0 net/bluetooth/rfcomm/core.c:426

stack backtrace:
CPU: 0 UID: 0 PID: 9473 Comm: syz-executor108 Not tainted 7.3.0-rc2
#42 PREEMPT(full)
Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix,
1996), 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+0x10e/0x190 lib/dump_stack.c:120
 print_circular_bug+0x37e/0x3a0 kernel/locking/lockdep.c:2087
 check_noncircular+0x12f/0x150 kernel/locking/lockdep.c:2219
 check_prev_add kernel/locking/lockdep.c:3209 [inline]
 check_prevs_add kernel/locking/lockdep.c:3328 [inline]
 validate_chain+0xa41/0x2560 kernel/locking/lockdep.c:3952
 __lock_acquire+0xbe0/0xf10 kernel/locking/lockdep.c:5288
 lock_acquire+0x116/0x350 kernel/locking/lockdep.c:5942
 __mutex_lock_common kernel/locking/mutex.c:646 [inline]
 __mutex_lock+0x184/0x1590 kernel/locking/mutex.c:821
 l2cap_chan_connect+0xa0/0x1130 net/bluetooth/l2cap_core.c:7281
 l2cap_sock_connect+0x5c8/0x7d0 net/bluetooth/l2cap_sock.c:255
 kernel_connect+0x116/0x180 net/socket.c:3755
 rfcomm_session_create net/bluetooth/rfcomm/core.c:808 [inline]
 __rfcomm_dlc_open net/bluetooth/rfcomm/core.c:385 [inline]
 rfcomm_dlc_open+0x924/0xee0 net/bluetooth/rfcomm/core.c:428
 rfcomm_sock_connect+0x2f7/0x650 net/bluetooth/rfcomm/sock.c:421
 connect_socket net/socket.c:2141 [inline]
 __sys_connect_file net/socket.c:2166 [inline]
 __sys_connect+0x30e/0x430 net/socket.c:2183
 __do_sys_connect net/socket.c:2189 [inline]
 __se_sys_connect net/socket.c:2186 [inline]
 __x64_sys_connect+0x7a/0x90 net/socket.c:2186
 do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
 do_syscall_64+0x170/0x540 arch/x86/entry/syscall_64.c:84
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f86d4e40b4d
Code: b3 66 2e 0f 1f 84 00 00 00 00 00 66 90 f3 0f 1e fa 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 b8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007fff9b4b4618 EFLAGS: 00000246 ORIG_RAX: 000000000000002a
RAX: ffffffffffffffda RBX: 0000000000000004 RCX: 00007f86d4e40b4d
RDX: 000000000000000a RSI: 0000200000000240 RDI: 0000000000000004
RBP: 0000000000000003 R08: 000000ff00ff7000 R09: 000000ff00ff7000
R10: 000000ff00ff7000 R11: 0000000000000246 R12: 000055558c9a6378
R13: 0000000000000010 R14: 00007f86d4ec50ce R15: 0000000000000001
 </TASK>

Following is the root cause analysis for this issue, note that the
analysis is performed with the assistance of LLM, but we try our best to
ensure the accuracy.

lockdep reports a cycle between three mutexes: hdev->lock, hci_cb_list_lock,
and rfcomm_mutex.  Two paths take the locks in opposite orders.  A connect()
on an RFCOMM socket runs the whole session setup under rfcomm_mutex, and the
L2CAP connection it opens along the way takes hdev->lock:

rfcomm_dlc_open() <-- takes rfcomm_mutex
 rfcomm_session_create()
   kernel_connect()
     l2cap_chan_connect() <-- takes hdev->lock

The other path starts at the controller.  hci_encrypt_cfm() and
hci_auth_cfm() are only ever called from HCI event handlers, which hold
hdev->lock, and the RFCOMM security callback takes rfcomm_mutex from there:

hci_encrypt_change_evt() <-- takes hdev->lock
 hci_encrypt_cfm() <-- takes hci_cb_list_lock
   rfcomm_security_cfm() <-- takes rfcomm_mutex

When the two paths overlap, hci_rx_work() blocks on rfcomm_mutex while
holding hdev->lock, and the connecting task blocks on hdev->lock while
holding rfcomm_mutex.  Neither can make progress, leading to a deadlock.

Following is our suggested solution: The confirmation callback only records
per-channel state that the krfcommd thread acts on later, so it does not
have to run in the event path at all.  Deferring it to an ordered workqueue
keeps that work serialized under rfcomm_mutex and takes rfcomm_mutex out of
the hdev->lock nesting.

We are actively working on a patch, if the above solution is acceptable,
I would be happy to submit a formal patch for review.

The kernel console output, kernel config, syzkaller reproducer, and C
reproducer are available at google drive:
https://drive.google.com/drive/folders/1Q-Eu5dpQCMH80lEtunLGvK-_oheGkT2O?usp=sharing

Please let us know if any further information is required.

Best Regards,
Jiaming Zhang

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

end of thread, other threads:[~2026-09-29  7:42 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-11 16:59 [Linux Kernel Bug] possible deadlock in l2cap_chan_connect Jiaming Zhang
2026-09-11 18:38 ` Ali Ahmet Memiş
2026-09-29  7:25   ` Mikhail Gavrilov
2026-09-29  7:41     ` Jiaming Zhang

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®