linux/include
Mikhail Gavrilov ac022970e9 Bluetooth: RFCOMM: connect the session socket without rfcomm_mutex
An RFCOMM connect() issued while a BR/EDR link is being authenticated
makes lockdep report a circular dependency, and the reported cycle is a
real AB/BA between rfcomm_mutex and hdev->lock.

rfcomm_security_cfm() is called from the HCI event path, which already
holds hdev->lock:

  hci_rx_work()
    hci_event_packet()
      hci_cc_read_enc_key_size()   [hdev->lock]
        hci_encrypt_cfm()          [hci_cb_list_lock]
          rfcomm_security_cfm()    [rfcomm_mutex]

while an RFCOMM connect() from userspace takes the same two locks the
other way round:

  rfcomm_sock_connect()
    rfcomm_dlc_open()              [rfcomm_mutex]
      __rfcomm_dlc_open()
        rfcomm_session_create()
          kernel_connect()
            l2cap_sock_connect()
              l2cap_chan_connect() [hdev->lock]

  WARNING: possible circular locking dependency detected
  kworker/u131:1/1128 is trying to acquire lock:
  rfcomm_mutex, at: rfcomm_security_cfm+0x31/0x3e0 [rfcomm]
  but task is already holding lock:
  hci_cb_list_lock, at: hci_cc_read_enc_key_size+0x1d2/0xcc0
  Chain exists of:
    rfcomm_mutex --> &hdev->lock --> hci_cb_list_lock

hci_auth_complete_evt() and hci_encrypt_change_evt() reach the callback
the same way.

Both orders have to be seen in the same boot, which is why a BR/EDR
connection alone is not enough to show it: a session set up by the
remote side is created by rfcomm_accept_connection() in krfcommd, which
calls kernel_accept() and never takes hdev->lock under rfcomm_mutex.
Connecting a device that authenticates and encrypts the link and then
calling connect() on an RFCOMM socket towards any address - the connect
does not have to succeed, the order is recorded before the page timeout
- reports it every time.

Only the session socket has to be connected with the lock held, and it
does not: nothing else can see the socket before it is put on the
session list.  So connect it first and take rfcomm_mutex afterwards,
which removes the rfcomm_mutex -> hdev->lock order for good, rather
than keeping the HCI event path out of rfcomm_mutex.

rfcomm_session_create() becomes rfcomm_session_connect(), which returns
the connected socket without touching the session list, and
rfcomm_dlc_open() adds the session once it holds the lock again.  If
another opener added a session for the same pair while this socket was
connecting, that session is used and this socket is dropped.
__rfcomm_dlc_open() now takes the session it should use, and its state
check runs after the lock is re-acquired, so a DLC that was opened or
closed in the meantime is still handled.

Over an existing ACL link the connection can complete before the
session reaches the list, and the wakeup from the socket callback is
then lost, so krfcommd is woken once the session is visible.

Connecting without the lock opens a window in which the socket can be
closed.  The DLC is not on a session yet, so rfcomm_dlc_close() finds
nothing to do and returns without touching it, and rfcomm_dlc_open()
would then attach a DLC whose owner is gone.  rfcomm_dlc_close() now
marks such a DLC with RFCOMM_CLOSED, and rfcomm_dlc_open() checks the
mark once it holds rfcomm_mutex again and drops the socket instead of
attaching the DLC.  The mark is cleared when an open starts, so a DLC
that is reused is not affected.  This covers both callers of
rfcomm_dlc_open(), the socket and the tty layer.

Fixes: 759c185d0b ("Bluetooth: RFCOMM: serialize security confirmation handling")
Suggested-by: Pauli Virtanen <pav@iki.fi>
Reported-by: Pauli Virtanen <pav@iki.fi>
Closes: https://lore.kernel.org/linux-bluetooth/5e76a95e934e451e7006db28827c2d64af5a88be.camel@iki.fi/
Reported-by: syzbot+74071deb72339c215b2e@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/linux-bluetooth/6a92fadc.08e933ee.dbf97.008f.GAE@google.com/
Reported-by: Jiaming Zhang <r772577952@gmail.com>
Closes: https://lore.kernel.org/all/CANypQFabseTuRiyz2pGkc_Qj0moGDnY7KEp1qdTOqkw6gAL3hw@mail.gmail.com/
Cc: stable@vger.kernel.org
Signed-off-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Tested-by: syzbot+74071deb72339c215b2e@syzkaller.appspotmail.com
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-29 10:44:07 -04:00
..
acpi ACPI: bus: Drop two fields from struct acpi_device_pnp 2026-09-01 21:45:50 +02:00
asm-generic kho: make boot time huge page allocation work nicely with KHO 2026-08-23 09:17:38 -07:00
clocksource hyperv-next for v7.3-rc1 2026-08-26 16:47:40 -07:00
crypto This update includes the following changes: 2026-08-19 17:25:42 -07:00
cxl
drm Merge drm/drm-fixes into drm-misc-fixes 2026-09-01 09:38:51 +02:00
dt-bindings sound fixes for 7.3-rc1 2026-08-28 10:01:02 -07:00
hyperv
keys tpm: Initial step to reorganize TPM public headers 2026-08-25 18:13:35 +03:00
kunit gpio updates for v7.3-rc1 2026-08-19 09:10:07 -07:00
kvm KVM/arm64 changes for 7.3 2026-08-24 12:42:07 -04:00
linux Nothing too exciting, usual stream of fixes. 2026-09-10 14:07:48 -07:00
math-emu
media
memory
misc
net Bluetooth: RFCOMM: connect the session socket without rfcomm_mutex 2026-09-29 10:44:07 -04:00
pcmcia
ras
rdma
rv mm.git review status for linus..mm-stable 2026-08-27 09:17:06 -07:00
scsi SCSI updates for 7.3 2026-08-29 11:55:36 -07:00
soc Mostly the usual clk driver updates and new SoC additions plus non-critical 2026-08-26 11:14:30 -07:00
sound ALSA: rawmidi: Another workaround for false-positive mutex lockdep warning 2026-08-25 15:55:37 +02:00
target
trace Landlock fix for v7.3-rc3 2026-09-09 11:00:35 -07:00
uapi integrity-v7.3-rc2 2026-09-04 19:36:11 -07:00
ufs
vdso
video fbdev: maxine: fix 64-bit build error 2026-08-20 23:45:07 +02:00
xen
Kbuild