mirror of https://github.com/torvalds/linux.git
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:
|
||
|---|---|---|
| .. | ||
| Kconfig | ||
| Makefile | ||
| ath3k.c | ||
| bcm203x.c | ||
| bfusb.c | ||
| bluecard_cs.c | ||
| bpa10x.c | ||
| bt3c_cs.c | ||
| btbcm.c | ||
| btbcm.h | ||
| btintel.c | ||
| btintel.h | ||
| btintel_pcie.c | ||
| btintel_pcie.h | ||
| btmrvl_debugfs.c | ||
| btmrvl_drv.h | ||
| btmrvl_main.c | ||
| btmrvl_sdio.c | ||
| btmrvl_sdio.h | ||
| btmtk.c | ||
| btmtk.h | ||
| btmtksdio.c | ||
| btmtkuart.c | ||
| btnxpuart.c | ||
| btqca.c | ||
| btqca.h | ||
| btqcomsmd.c | ||
| btrsi.c | ||
| btrtl.c | ||
| btrtl.h | ||
| btsdio.c | ||
| btusb.c | ||
| dtl1_cs.c | ||
| hci_ag6xx.c | ||
| hci_aml.c | ||
| hci_ath.c | ||
| hci_bcm.c | ||
| hci_bcm4377.c | ||
| hci_bcsp.c | ||
| hci_h4.c | ||
| hci_h5.c | ||
| hci_intel.c | ||
| hci_ldisc.c | ||
| hci_ll.c | ||
| hci_mrvl.c | ||
| hci_nokia.c | ||
| hci_qca.c | ||
| hci_serdev.c | ||
| hci_uart.h | ||
| hci_vhci.c | ||
| virtio_bt.c | ||