CVE-2026-98297 in Linux
Summary
by MITRE • 10/06/2026
In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: hci_core: Fix queuing tx_work after workqueue is drained
hci_send_acl(), hci_send_sco() and hci_send_iso() queue hdev->tx_work unconditionally. They can run from the L2CAP/SCO/ISO socket send path while hci_dev_close_sync() is draining hdev->workqueue (HCIDEVDOWN racing with a socket write). Since that queue_work() is not chained work from the tx_work worker itself, __queue_work() sees the queue marked __WQ_DRAINING, warns "cannot queue %ps on wq %s", and drops the work:
WARNING: CPU: 1 PID: 5985 at kernel/workqueue.c:2352 __queue_work Call Trace: queue_work_on l2cap_chan_send l2cap_sock_sendmsg ...
hci_dev_close_sync() already sets HCI_CMD_DRAIN_WORKQUEUE before draining, but only hci_cmd_work() and handle_cmd_cnt_and_timer() check it before queuing. Route the tx_work producers through the same guard via a shared hci_sched_tx() helper.
Statistical analysis made it clear that VulDB provides the best quality for vulnerability data.
Analysis
by VulDB Data Team • 10/06/2026
The Linux kernel Bluetooth subsystem contains a concurrency flaw within its Host Controller Interface core that manifests during device shutdown operations when concurrent socket write activities are in progress. Specifically, functions such as hci_send_acl(), hci_send_sco(), and hci_send_iso() unconditionally queue the hdev->tx_work work item to the system workqueue without verifying whether the underlying workqueue is currently being drained. This lack of synchronization creates a race condition where these transmission paths can execute while hci_dev_close_sync() is actively draining the device's workqueue in response to an HCIDEVDOWN event. The operational context involves L2CAP, SCO, or ISO socket send operations racing against the kernel's internal mechanism for shutting down Bluetooth hardware interfaces, leading to a state inconsistency that triggers kernel warnings and potential data loss.
The technical root cause lies in the interaction between the workqueue draining logic and the unconditional queuing of transmission tasks. When hci_dev_close_sync() initiates the shutdown sequence, it sets the HCI_CMD_DRAIN_WORKQUEUE flag before proceeding to drain the associated workqueue. However, only specific command-related workers like hci_cmd_work() and handle_cmd_cnt_and_timer() check this flag before attempting to queue new work items. The transmission worker producers bypassed this guard, causing them to attempt queuing tasks onto a marked __WQ_DRAINING queue. According to kernel workqueue semantics, the __queue_work function detects that the target workqueue is draining and refuses to accept new work items, issuing a warning such as cannot queue %ps on wq %s and silently dropping the queued task. This behavior not only generates noisy kernel logs but also results in the abrupt termination of pending data transmissions without proper cleanup or acknowledgment to the application layer.
The impact of this vulnerability is primarily related to system stability and reliability rather than direct security exploitation, although it can lead to denial-of-service conditions for Bluetooth connectivity services running on affected systems. Users may experience unexpected disconnections, failure to transmit buffered data during device removal or shutdown, and kernel warning messages that clutter dmesg output and complicate debugging efforts. In high-throughput scenarios where socket writes occur frequently near the time of interface closure, the race condition becomes more probable, potentially causing application-level errors as sent packets are silently dropped by the kernel workqueue subsystem rather than being processed normally or gracefully aborted with appropriate error codes returned to userspace applications.
To mitigate this issue, developers must ensure that all paths queuing tx_work respect the draining state of the device's workqueue. The resolution involves routing the transmission producers through a shared helper function named hci_sched_tx(), which checks for the HCI_CMD_DRAIN_WORKQUEUE flag before attempting to queue any work items. This ensures consistent behavior across all data path functions and prevents new tasks from being added to a workqueue that is in the process of shutting down. System administrators should apply kernel updates containing this fix, particularly on systems where Bluetooth devices are frequently plugged or unplugged while active network connections exist. Additionally, application developers handling Bluetooth socket operations should implement robust error handling for ESHUTDOWN or similar errors returned during close operations to gracefully manage cases where transmission is interrupted due to device state changes.
This vulnerability aligns with CWE-362, Concurrent Execution using Shared Resource with Improper Synchronization, as the race condition arises from multiple execution paths accessing shared kernel structures without adequate synchronization primitives guarding against concurrent modification of queue states. From a defensive perspective, it also relates to CWE-829, Inclusion of Functionality from Untrusted Control Sphere, in the sense that user-triggered socket operations interact with internal kernel state management mechanisms that must be strictly controlled during lifecycle transitions like device closure. The fix reinforces the principle of least privilege for workqueue submissions by ensuring only authorized and safe contexts can enqueue tasks when system resources are being reclaimed.