From: Ronald Tschalär Date: Thu, 26 Oct 2017 05:15:19 +0000 (-0700) Subject: Bluetooth: hci_ldisc: Fix another race when closing the tty. X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=e508e6026b198b9879e0d1850fdef8ef1d4d0805;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git Bluetooth: hci_ldisc: Fix another race when closing the tty. [ Upstream commit 0338b1b393ec7910898e8f7b25b3bf31a7282e16 ] The following race condition still existed: P1 P2 cancel_work_sync() hci_uart_tx_wakeup() hci_uart_write_work() hci_uart_dequeue() clear_bit(HCI_UART_PROTO_READY) hci_unregister_dev(hdev) hci_free_dev(hdev) hu->proto->close(hu) kfree(hu) access to hdev and hu Cancelling the work after clearing the HCI_UART_PROTO_READY bit avoids this as any hci_uart_tx_wakeup() issued after the flag is cleared will detect that and not schedule further work. Signed-off-by: Ronald Tschalär Reviewed-by: Lukas Wunner Signed-off-by: Marcel Holtmann Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index a746627e784e..6e2403805784 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -510,13 +510,13 @@ static void hci_uart_tty_close(struct tty_struct *tty) if (hdev) hci_uart_close(hdev); - cancel_work_sync(&hu->write_work); - if (test_bit(HCI_UART_PROTO_READY, &hu->flags)) { write_lock_irqsave(&hu->proto_lock, flags); clear_bit(HCI_UART_PROTO_READY, &hu->flags); write_unlock_irqrestore(&hu->proto_lock, flags); + cancel_work_sync(&hu->write_work); + if (hdev) { if (test_bit(HCI_UART_REGISTERED, &hu->flags)) hci_unregister_dev(hdev);