mirror-linux/drivers/bluetooth
Mingyu Wang c1bb9336ae Bluetooth: hci_uart: fix UAFs and race conditions in close and init paths
Vulnerabilities leading to Use-After-Free (UAF) and Null Pointer
Dereference (NPD) conditions were observed in the lifecycle management
of hci_uart.

The primary issue arises because the workqueues (init_ready and
write_work) are only flushed/cancelled if the HCI_UART_PROTO_READY
flag is set during TTY close. If a hangup occurs before setup completes,
hci_uart_tty_close() skips the teardown of these workqueues and
proceeds to free the `hu` struct. When the scheduled work executes
later, it blindly dereferences the freed `hu` struct.

Furthermore, several data races and UAFs were identified in the teardown
sequence:
1. Calling hci_uart_flush() from hci_uart_close() without effectively
   disabling write_work causes a race condition where both can concurrently
   double-free hu->tx_skb. This happens because protocol timers can
   concurrently invoke hci_uart_tx_wakeup() and requeue write_work.
2. Calling hci_free_dev(hdev) before hu->proto->close(hu) causes a UAF
   when vendor specific protocol close callbacks dereference hu->hdev.
3. In the initialization error paths, failing to take the proto_lock
   write lock before clearing PROTO_READY leads to races with active
   readers. Additionally, hci_uart_tty_receive() accesses hu->hdev
   outside the read lock, leading to UAFs if the initialization error
   path frees hdev concurrently.

Fix these synchronization and lifecycle issues by:
1. Re-ordering hci_uart_tty_close() to clear HCI_UART_PROTO_READY first,
   followed immediately by a cancel_work_sync(&hu->write_work). Clearing
   the flag locks out concurrent protocol timers from successfully invoking
   hci_uart_tx_wakeup(), effectively rendering the cancellation permanent
   and preventing the tx_skb double-free.
2. Note: Clearing PROTO_READY early causes hci_uart_close() to skip
   hu->proto->flush(). This is perfectly safe in the tty_close path
   because hu->proto->close() executes shortly after, which intrinsically
   purges all protocol SKB queues and tears down the state.
3. Relocating hu->proto->close(hu) strictly prior to hci_free_dev(hdev)
   across all close and error paths to prevent vendor-level UAFs.
4. Moving the hdev->stat.byte_rx increment in hci_uart_tty_receive()
   inside the proto_lock read-side critical section to safely synchronize
   with device unregistration.
5. Adding cancel_work_sync(&hu->write_work) to hci_uart_close() to safely
   flush the workqueue before hci_uart_flush() is invoked via the HCI core.
6. Utilizing cancel_work_sync() instead of disable_work_sync() across
   all paths to prevent permanently breaking user-space retry capabilities.

Fixes: 3b799254cf ("Bluetooth: hci_uart: Cancel init work before unregistering")
Cc: stable@vger.kernel.org
Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-05-20 16:35:47 -04:00
..
Kconfig Bluetooth: hci_h5: implement CRC data integrity 2025-12-01 15:58:54 -05:00
Makefile Bluetooth: hci_uart: Add support for Amlogic HCI UART 2024-09-10 12:44:10 -04:00
ath3k.c move asm/unaligned.h to linux/unaligned.h 2024-10-02 17:23:23 -04:00
bcm203x.c
bfusb.c Bluetooth: hci_dev: replace 'quirks' integer by 'quirk_flags' bitmap 2025-07-16 15:37:53 -04:00
bluecard_cs.c treewide, timers: Rename from_timer() to timer_container_of() 2025-06-08 09:07:37 +02:00
bpa10x.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
bt3c_cs.c
btbcm.c Bluetooth: btbcm: Add entry for BCM4343A2 UART Bluetooth 2026-04-10 10:22:21 -04:00
btbcm.h
btintel.c Bluetooth: btintel: Add support for Scorpious Peak2F support 2026-04-10 10:28:44 -04:00
btintel.h Bluetooth: btintel_pcie: Add support for exception dump for ScP2F 2026-04-10 10:29:03 -04:00
btintel_pcie.c Bluetooth: btintel_pcie: Fix incorrect MAC access programming 2026-05-20 16:35:47 -04:00
btintel_pcie.h Bluetooth: btintel_pcie: Fix incorrect MAC access programming 2026-05-20 16:35:47 -04:00
btmrvl_debugfs.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
btmrvl_drv.h
btmrvl_main.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
btmrvl_sdio.c Bluetooth: btmrvl_sdio: Fix wakeup source leaks on device unbind 2025-05-21 10:27:20 -04:00
btmrvl_sdio.h
btmtk.c Bluetooth: btmtk: fix urb->setup_packet leak in error paths 2026-05-20 16:35:47 -04:00
btmtk.h Bluetooth: btmtk: Add MT6639 (MT7927) Bluetooth support 2026-04-13 09:18:16 -04:00
btmtksdio.c Bluetooth: btmtk: Add MT6639 (MT7927) Bluetooth support 2026-04-13 09:18:16 -04:00
btmtkuart.c Bluetooth: fix corruption in h4_recv_buf() after cleanup 2025-10-24 10:31:24 -04:00
btnxpuart.c Bluetooth: btnxpuart: Remove unneeded CONFIG_PM ifdef 2026-01-29 13:34:25 -05:00
btqca.c Bluetooth: qca: Refactor code on the basis of chipset names 2026-04-10 10:22:00 -04:00
btqca.h Bluetooth: qca: add WCN3950 support 2025-03-25 12:42:35 -04:00
btqcomsmd.c Bluetooth: hci_dev: replace 'quirks' integer by 'quirk_flags' bitmap 2025-07-16 15:37:53 -04:00
btrsi.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
btrtl.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
btrtl.h Bluetooth: btrtl: Add Realtek devcoredump support 2023-08-11 11:35:14 -07:00
btsdio.c Bluetooth: hci_dev: replace 'quirks' integer by 'quirk_flags' bitmap 2025-07-16 15:37:53 -04:00
btusb.c Bluetooth: btusb: MediaTek MT7922: Add VID 0489 & PID e11d 2026-04-13 09:19:42 -04:00
dtl1_cs.c
hci_ag6xx.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
hci_aml.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
hci_ath.c Bluetooth: hci_uart: Fix NULL deref in recv callbacks when priv is uninitialized 2026-05-06 16:21:43 -04:00
hci_bcm.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
hci_bcm4377.c Bluetooth: hci_bcm4377: Use generic power management 2026-01-29 13:22:42 -05:00
hci_bcsp.c Bluetooth: hci_uart: Fix NULL deref in recv callbacks when priv is uninitialized 2026-05-06 16:21:43 -04:00
hci_h4.c Bluetooth: hci_uart: Fix NULL deref in recv callbacks when priv is uninitialized 2026-05-06 16:21:43 -04:00
hci_h5.c Bluetooth: hci_uart: Fix NULL deref in recv callbacks when priv is uninitialized 2026-05-06 16:21:43 -04:00
hci_intel.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
hci_ldisc.c Bluetooth: hci_uart: fix UAFs and race conditions in close and init paths 2026-05-20 16:35:47 -04:00
hci_ll.c Bluetooth: hci_ll: Enable BROKEN_ENHANCED_SETUP_SYNC_CONN for WL183x 2026-04-13 09:19:42 -04:00
hci_mrvl.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
hci_nokia.c Bluetooth: fix corruption in h4_recv_buf() after cleanup 2025-10-24 10:31:24 -04:00
hci_qca.c Bluetooth: hci_qca: Convert timeout from jiffies to ms 2026-05-14 09:58:08 -04:00
hci_serdev.c Bluetooth: hci_dev: replace 'quirks' integer by 'quirk_flags' bitmap 2025-07-16 15:37:53 -04:00
hci_uart.h Bluetooth: fix corruption in h4_recv_buf() after cleanup 2025-10-24 10:31:24 -04:00
hci_vhci.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
virtio_bt.c Bluetooth: virtio_bt: validate rx pkt_type header length 2026-05-06 16:22:33 -04:00