CVE-2026-46275
Publication date:
08/06/2026
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
Bluetooth: hci_uart: fix UAFs and race conditions in close and init paths<br />
<br />
Vulnerabilities leading to Use-After-Free (UAF) and Null Pointer<br />
Dereference (NPD) conditions were observed in the lifecycle management<br />
of hci_uart.<br />
<br />
The primary issue arises because the workqueues (init_ready and<br />
write_work) are only flushed/cancelled if the HCI_UART_PROTO_READY<br />
flag is set during TTY close. If a hangup occurs before setup completes,<br />
hci_uart_tty_close() skips the teardown of these workqueues and<br />
proceeds to free the `hu` struct. When the scheduled work executes<br />
later, it blindly dereferences the freed `hu` struct.<br />
<br />
Furthermore, several data races and UAFs were identified in the teardown<br />
sequence:<br />
1. Calling hci_uart_flush() from hci_uart_close() without effectively<br />
disabling write_work causes a race condition where both can concurrently<br />
double-free hu->tx_skb. This happens because protocol timers can<br />
concurrently invoke hci_uart_tx_wakeup() and requeue write_work.<br />
2. Calling hci_free_dev(hdev) before hu->proto->close(hu) causes a UAF<br />
when vendor specific protocol close callbacks dereference hu->hdev.<br />
3. In the initialization error paths, failing to take the proto_lock<br />
write lock before clearing PROTO_READY leads to races with active<br />
readers. Additionally, hci_uart_tty_receive() accesses hu->hdev<br />
outside the read lock, leading to UAFs if the initialization error<br />
path frees hdev concurrently.<br />
<br />
Fix these synchronization and lifecycle issues by:<br />
1. Re-ordering hci_uart_tty_close() to clear HCI_UART_PROTO_READY first,<br />
followed immediately by a cancel_work_sync(&hu->write_work). Clearing<br />
the flag locks out concurrent protocol timers from successfully invoking<br />
hci_uart_tx_wakeup(), effectively rendering the cancellation permanent<br />
and preventing the tx_skb double-free.<br />
2. Note: Clearing PROTO_READY early causes hci_uart_close() to skip<br />
hu->proto->flush(). This is perfectly safe in the tty_close path<br />
because hu->proto->close() executes shortly after, which intrinsically<br />
purges all protocol SKB queues and tears down the state.<br />
3. Relocating hu->proto->close(hu) strictly prior to hci_free_dev(hdev)<br />
across all close and error paths to prevent vendor-level UAFs.<br />
4. Moving the hdev->stat.byte_rx increment in hci_uart_tty_receive()<br />
inside the proto_lock read-side critical section to safely synchronize<br />
with device unregistration.<br />
5. Adding cancel_work_sync(&hu->write_work) to hci_uart_close() to safely<br />
flush the workqueue before hci_uart_flush() is invoked via the HCI core.<br />
6. Utilizing cancel_work_sync() instead of disable_work_sync() across<br />
all paths to prevent permanently breaking user-space retry capabilities.
Severity CVSS v4.0: Pending analysis
Last modification:
08/07/2026