This is a note to let you know that I've just added the patch titled Bluetooth: hci_uart: Cancel init work before unregistering to the 4.14-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: bluetooth-hci_uart-cancel-init-work-before-unregiste.patch and it can be found in the queue-4.14 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. commit 19776d0f168cb8c5a6bec50f934ce2f9f5b390b9 Author: Samuel Holland <samuel@xxxxxxxxxxxx> Date: Sat Aug 1 11:29:56 2020 -0500 Bluetooth: hci_uart: Cancel init work before unregistering [ 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@xxxxxxxxxxxx> Signed-off-by: Marcel Holtmann <marcel@xxxxxxxxxxxx> Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx> diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 43221def1d29f..f19606019eb01 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -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) { diff --git a/drivers/bluetooth/hci_serdev.c b/drivers/bluetooth/hci_serdev.c index 72cf2d97b682c..196b046658ff4 100644 --- a/drivers/bluetooth/hci_serdev.c +++ b/drivers/bluetooth/hci_serdev.c @@ -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);