Bluetooth: hci_uart: Cancel init work before unregistering
authorSamuel Holland <samuel@sholland.org>
Sat, 1 Aug 2020 16:29:56 +0000 (11:29 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 Oct 2020 08:07:03 +0000 (09:07 +0100)
[ Upstream commit 3b799254cf6f481460719023d7a18f46651e5e7f ]

If hci_uart_tty_close() or hci_uart_unregister_device() is called while
hu->init_ready is scheduled, hci_register_dev() could be called after
the hci_uart is torn down. Avoid this by ensuring the work is complete
or canceled before checking the HCI_UART_REGISTERED flag.

Fixes: 9f2aee848fe6 ("Bluetooth: Add delayed init sequence support for UART controllers")
Signed-off-by: Samuel Holland <samuel@sholland.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/bluetooth/hci_ldisc.c
drivers/bluetooth/hci_serdev.c

index 43221def1d29feafb6a9f77740f9309000b4f5d9..f19606019eb010cac1460da9f831451b4346e8ac 100644 (file)
@@ -541,6 +541,7 @@ static void hci_uart_tty_close(struct tty_struct *tty)
                clear_bit(HCI_UART_PROTO_READY, &hu->flags);
                percpu_up_write(&hu->proto_lock);
 
+               cancel_work_sync(&hu->init_ready);
                cancel_work_sync(&hu->write_work);
 
                if (hdev) {
index 72cf2d97b682c17b58f556f75ab073fa079f206b..196b046658ff42c56ab1a5966b92abfd9805a72e 100644 (file)
@@ -361,6 +361,8 @@ void hci_uart_unregister_device(struct hci_uart *hu)
        struct hci_dev *hdev = hu->hdev;
 
        clear_bit(HCI_UART_PROTO_READY, &hu->flags);
+
+       cancel_work_sync(&hu->init_ready);
        if (test_bit(HCI_UART_REGISTERED, &hu->flags))
                hci_unregister_dev(hdev);
        hci_free_dev(hdev);