Bluetooth: hci_uart: fix null-ptr-deref in hci_uart_write_work
hci_uart_set_proto() sets HCI_UART_PROTO_INIT before calling
hci_uart_register_dev(), which calls proto->open() to initialize
hu->priv. However, if a TTY write wakeup occurs during this window,
hci_uart_tx_wakeup() may schedule write_work before hu->priv is
initialized, leading to a NULL pointer dereference in
hci_uart_write_work() when proto->dequeue() accesses hu->priv.
The race condition is:
CPU0 CPU1
---- ----
hci_uart_set_proto()
set_bit(HCI_UART_PROTO_INIT)
hci_uart_register_dev()
tty write wakeup
hci_uart_tty_wakeup()
hci_uart_tx_wakeup()
schedule_work(&hu->write_work)
proto->open(hu)
// initializes hu->priv
hci_uart_write_work()
hci_uart_dequeue()
proto->dequeue(hu)
// accesses hu->priv (NULL!)
Fix this by moving set_bit(HCI_UART_PROTO_INIT) after proto->open()
succeeds, ensuring hu->priv is initialized before any work can be
scheduled.
Fixes: 5df5dafc17 ("Bluetooth: hci_uart: Fix another race during initialization")
Link: https://lore.kernel.org/linux-bluetooth/6969764f.170a0220.2b9fc4.35a7@mx.google.com/
Signed-off-by: Jia-Hong Su <s11242586@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
4a3dba4818
commit
0c3cd7a0b8
|
|
@ -685,6 +685,8 @@ static int hci_uart_register_dev(struct hci_uart *hu)
|
|||
return err;
|
||||
}
|
||||
|
||||
set_bit(HCI_UART_PROTO_INIT, &hu->flags);
|
||||
|
||||
if (test_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags))
|
||||
return 0;
|
||||
|
||||
|
|
@ -712,8 +714,6 @@ static int hci_uart_set_proto(struct hci_uart *hu, int id)
|
|||
|
||||
hu->proto = p;
|
||||
|
||||
set_bit(HCI_UART_PROTO_INIT, &hu->flags);
|
||||
|
||||
err = hci_uart_register_dev(hu);
|
||||
if (err) {
|
||||
return err;
|
||||
|
|
|
|||
Loading…
Reference in New Issue