Cloudanix VulnDB

CVE-2026-99009

None

CVSS

—

EPSS

0.2%

Published

Oct 23, 2026

CISA due date

—

Cloudanix analysis

Schedule a fix SSVC: Track

A locking mistake in the Linux kernel's Bluetooth code can cause the system to freeze when certain wireless connections are made.

Exploitation
Local Privilege
Attacker needs
Local User
Complexity
Moderate
Impact
Denial Of Service
Component
OS kernel
Class
Race Condition
Remediation
Upgrade
Effort
Medium
Patch risk
Low

What it actually does

Creates a circular locking dependency between rfcomm_mutex and hdev->lock in the Linux kernel Bluetooth RFCOMM subsystem during BR/EDR link authentication combined with session socket connect operations, allowing a real AB/BA deadlock.

Why it matters to the business

Bluetooth connections on Linux systems can trigger kernel lockdep warnings followed by hangs or unresponsiveness in RFCOMM-based services such as serial emulation over Bluetooth, disrupting dependent applications and requiring reboots.

How an attack unfolds

An attacker initiates a BR/EDR link that requires authentication and encryption, then issues an RFCOMM connect from userspace while the HCI event path holds the device lock; the reverse lock acquisition order in rfcomm_security_cfm and rfcomm_dlc_open records the deadlock cycle, which can be triggered repeatedly without needing a successful connection.

How to fix it

Apply the upstream kernel patch that reorders locking so rfcomm_session_connect acquires the socket before taking rfcomm_mutex, or upgrade to a Linux kernel release containing the fix for this race condition.

How to confirm the fix worked

Reproduce the described Bluetooth authentication plus RFCOMM connect sequence and confirm absence of lockdep circular dependency warnings in dmesg; verify that rfcomm_dlc_open and rfcomm_session_connect paths no longer create the mutex-to-hdev lock order.

Typical attack path

  1. Establish a BR/EDR ACL link requiring authentication and encryption
  2. Trigger hci_auth_complete_evt or hci_encrypt_change_evt to invoke rfcomm_security_cfm under hdev->lock
  3. Issue rfcomm_sock_connect from userspace to acquire rfcomm_mutex first then hdev->lock
  4. Observe lockdep-reported cycle and resulting deadlock or stalled krfcommd thread

How to detect it

Inspect kernel logs and dmesg for lockdep warnings that mention rfcomm_mutex being acquired while hdev->lock or hci_cb_list_lock is already held, or stalls in krfcommd and hci_rx_work threads during Bluetooth pairing and RFCOMM socket activity.

  • rfcomm_mutex
  • circular locking dependency detected
  • kworker.*trying to acquire lock.*rfcomm_mutex
  • Chain exists of: rfcomm_mutex --> &hdev->lock --> hci_cb_list_lock

What your security team should do

  • Prioritize kernel updates for systems with active Bluetooth RFCOMM usage within the next maintenance window
  • Monitor kernel logs for lockdep warnings involving rfcomm_mutex and hci device locks
  • Temporarily disable RFCOMM if Bluetooth serial emulation is non-essential until patched

The record

In the Linux kernel, the following vulnerability has been resolved: 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.

Affected packages

Ecosystem Package Introduced Fixed