[BUG] Bluetooth: rfcomm: possible circular locking dependency in the SAK vs. connect path

From: CJ <hidden>
Date: 2026-09-21 10:06:10
Also in: linux-bluetooth, lkml

Hi,


I am reporting an issue triggered by a syzkaller reproducer on Linux
7.3.0-rc2. The issue is reproducible with HEAD commit
df2908090cda368b01ff43709f51890076c56157.


The reproducer creates an RFCOMM socket on a vhci-backed HCI device, binds
and listens on it, and then injects four crafted RFCOMM frames through
syz_emit_vhci(). The frames drive the RFCOMM receiver into the connection
indication path.


Lockdep reports a circular locking dependency involving rfcomm. On the
reporting side the task holds console_lock (taken in vc_SAK) and tries to
acquire the tty buffer lock (&buf->lock, at tty_buffer_flush); the reverse
dependency chain shows console_lock being acquired by con_flush_chars() from
n_tty_write(). The lock class of interest for rfcomm is entered through
lock_sock_nested() from rfcomm_connect_ind(), which the earlier report on
linux-6.1 also showed.


This looks like a lock ordering problem between the RFCOMM receive/setup
path and the tty/console teardown path, rather than a specific bad pointer.
The earlier report against the same reproducer described the matching edge
of the cycle, with tty termios_rwsem taken at n_tty_flush_buffer() while
holding the tty buffer lock, so the cycle has been reachable for a while and
the participating locks are the same. Serializing the RFCOMM session setup
and teardown against the socket lock would be the direction; I have not
verified which of the recent RFCOMM locking changes already covers it.


This failure was reported earlier against the linux-6.1 longterm series at
https://syzkaller.appspot.com/bug?extid=3a1f869dcd8f26e5c216, and the
reproducer below is the one from that report. It still reproduces on the
tested mainline kernel.


Reproducer:


syz reproducer:
The reproducer is the program below, which requires no large encoded image:


r0 = syz_init_net_socket$bt_rfcomm(0x1f, 0x1, 0x3)
bind$bt_rfcomm(r0, &(0x7f0000000000)={0x1f, @any, 0x1}, 0xa)
listen(r0, 0x5)
syz_emit_vhci(&(0x7f0000000200)=ANY=[@ANYBLOB="02c8200c00080001000202040003004000"], 0x11)
syz_emit_vhci(&(0x7f0000000300)=ANY=[@ANYBLOB="02c8200c00080001000403040040000000"], 0x11)
syz_emit_vhci(&(0x7f0000000400)=ANY=[@ANYBLOB="02c8200e000a00010005010600400000000000"], 0x13)
syz_emit_vhci(&(0x7f0000000600)=ANY=[@ANYBLOB="02c82012000e00400003ef158311020007007f00000770"], 0x17)


console output: https://pastebin.com/raw/zLyVGhi5
kernel config: https://syzkaller.appspot.com/text?tag=KernelConfig&x=31dfefc4a14efea3


Kernel:


HEAD commit: df2908090cda368b01ff43709f51890076c56157
git tree: mainline
kernel version: 7.3.0-rc2
tested tag: v7.3-rc2 (annotated tag object 5e036ce12de91c6fd674dad33b169c6150be2a7a)


Let me know if you need more details or testing.


Best regards,
Changjian Liu 
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help