diff options
| author | ZhaoJinming <zhaojinming@uniontech.com> | 2026-08-10 15:08:45 +0800 |
|---|---|---|
| committer | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2026-08-11 15:40:21 -0400 |
| commit | 3ea6bd32027681ca83780fdad398804bdb5e3e4d (patch) | |
| tree | edb8e86c124a0844eb922a25d5099d2722145c1d /scripts/objdiff | |
| parent | fca8fe6149048c71ea8863f22674a8fc3cd84f2e (diff) | |
| download | linux-next-3ea6bd32027681ca83780fdad398804bdb5e3e4d.tar.gz linux-next-3ea6bd32027681ca83780fdad398804bdb5e3e4d.zip | |
Bluetooth: hci_serdev: Fix use-after-free in hci_uart_unregister_device()
hci_uart_unregister_device() frees the HCI device (hci_free_dev)
before cancelling write_work via cancel_work_sync(). If write_work
is executing concurrently on another CPU, it can access hu->hdev
and write to hdev->stat after the memory has been freed.
Additionally, HCI_UART_PROTO_READY is not cleared until after
cancel_work_sync, so the write_wakeup serdev callback can still
schedule write_work via hci_uart_tx_wakeup() even after
hci_free_dev has freed the device.
Fix this by mirroring the same ordering used in the tty/ldisc path
(hci_uart_tty_close, hci_ldisc.c:565-593):
1. Save the PROTO_READY state and clear it under the write lock so
a concurrent hci_uart_tx_wakeup() cannot re-schedule write_work
2. Cancel write_work (no new work can be scheduled and no work is
in flight)
3. Unregister the HCI device
4. Close the protocol (may access hu->hdev and the serdev device)
5. Close the serdev port (safe now that write_work is quiesced and
protocol is done)
6. Free the HCI device
Also free any partially transmitted frame (hu->tx_skb) left over by
write_work once the transmit path is quiesced, since hci_uart_close()
would skip hci_uart_flush() because HCI_UART_PROTO_READY is cleared.
Signed-off-by: ZhaoJinming <zhaojinming@uniontech.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Diffstat (limited to 'scripts/objdiff')
0 files changed, 0 insertions, 0 deletions
