mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 02:01:18 -04:00
Bluetooth: hci_ldisc: Clear HCI_UART_PROTO_INIT on error
When hci_register_dev() fails in hci_uart_register_dev()
HCI_UART_PROTO_INIT is not cleared before calling hu->proto->close(hu)
and setting hu->hdev to NULL. This means incoming UART data will reach
the protocol-specific recv handler in hci_uart_tty_receive() after
resources are freed.
Clear HCI_UART_PROTO_INIT with a write lock before calling
hu->proto->close() and setting hu->hdev to NULL. The write lock ensures
all active readers have completed and no new reader can enter the
protocol recv path before resources are freed.
This allows the protocol-specific recv functions to remove the
"HCI_UART_REGISTERED" guard without risking a null pointer dereference
if hci_register_dev() fails.
Fixes: 5df5dafc17 ("Bluetooth: hci_uart: Fix another race during initialization")
Signed-off-by: Jonathan Rissanen <jonathan.rissanen@axis.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
committed by
Luiz Augusto von Dentz
parent
d288f4db09
commit
68d39ea5e0
@@ -692,6 +692,9 @@ static int hci_uart_register_dev(struct hci_uart *hu)
|
||||
|
||||
if (hci_register_dev(hdev) < 0) {
|
||||
BT_ERR("Can't register HCI device");
|
||||
percpu_down_write(&hu->proto_lock);
|
||||
clear_bit(HCI_UART_PROTO_INIT, &hu->flags);
|
||||
percpu_up_write(&hu->proto_lock);
|
||||
hu->proto->close(hu);
|
||||
hu->hdev = NULL;
|
||||
hci_free_dev(hdev);
|
||||
|
||||
Reference in New Issue
Block a user