All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Bluetooth: btintel_pcie: Fix NULL hdev dereference in debug register dump
@ 2026-10-13 23:35 Chia-Lin Kao (AceLan)
  2026-10-14  2:15 ` bluez.test.bot
  2026-10-15  3:02 ` [PATCH] " AceLan Kao
  0 siblings, 2 replies; 3+ messages in thread
From: Chia-Lin Kao (AceLan) @ 2026-10-13 23:35 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz
  Cc: Kiran K, Chandrashekar Devegowda, linux-bluetooth, linux-kernel

The MSI-X interrupts are set up in btintel_pcie_config_pcie() and the
controller is brought out of reset in btintel_pcie_enable_bt(), both
long before btintel_pcie_setup_hdev() allocates the hci_dev.  On top of
that, data->hdev is only published after hci_register_dev() succeeds.
Until then, any interrupt that reaches an error path sees a NULL
data->hdev.

btintel_pcie_dump_debug_registers() is called from those error paths
with data->hdev and dereferences it immediately via hci_get_drvdata().
If the controller raises such an interrupt during probe, the IRQ thread
oopses.  The bt_dev_*() logging helpers are fine with a NULL hdev (they
print "null" as the device name), so the crash is only in the register
dump.

This was seen on an HP ZBook X G2i (8086:e376) with v7.3-rc7, where the
GP1 mailbox interrupt was handled right after the device was enabled:

  btintel_pcie 0000:00:14.7: enabling device (0000 -> 0002)
  Bluetooth: null: Received gp1 mailbox interrupt
  Oops: general protection fault, kernel NULL pointer dereference 0xda0
  CPU: 11 UID: 0 PID: 671 Comm: irq/213-btintel
  RIP: 0010:btintel_pcie_dump_debug_registers+0x20/0x910 [btintel_pcie]
  Call Trace:
   btintel_pcie_irq_msix_handler+0x1ca/0x6b0 [btintel_pcie]
   irq_thread_fn+0x26/0x70
   irq_thread+0x1b1/0x300

The IRQ thread then dies in do_exit() and the module load and the
following power off block behind it.  The GP1 handler no longer calls
the dump helper in current linux-next, but the GP0 handler still does
for the "Controller in error state" and "Controller in lockdown state"
cases, which have the same exposure during probe.

Return early from btintel_pcie_dump_debug_registers() when there is no
hci_dev yet.  The register dump is delivered through hci_recv_diag(),
so there is nowhere to send it without an hdev anyway; the preceding
bt_dev_err() has already reported the event.

Fixes: 190377500fde ("Bluetooth: btintel_pcie: Dump debug registers on error")
Cc: stable@vger.kernel.org
Signed-off-by: Chia-Lin Kao (AceLan) <acelan.kao@canonical.com>
---
 drivers/bluetooth/btintel_pcie.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
index 3a555aa50c87..fcdea1302cf7 100644
--- a/drivers/bluetooth/btintel_pcie.c
+++ b/drivers/bluetooth/btintel_pcie.c
@@ -433,12 +433,21 @@ static void btintel_pcie_prepare_tx(struct txq *txq, u16 tfd_index,
 
 static inline void btintel_pcie_dump_debug_registers(struct hci_dev *hdev)
 {
-	struct btintel_pcie_data *data = hci_get_drvdata(hdev);
+	struct btintel_pcie_data *data;
 	u16 cr_hia, cr_tia;
 	u32 reg, mbox_reg;
 	struct sk_buff *skb;
 	u8 buf[80];
 
+	/* The interrupts are enabled before the hci_dev is allocated and
+	 * data->hdev is published only after hci_register_dev() succeeds, so
+	 * an interrupt handler can get here with a NULL hdev.
+	 */
+	if (!hdev)
+		return;
+
+	data = hci_get_drvdata(hdev);
+
 	skb = alloc_skb(1024, GFP_ATOMIC);
 	if (!skb)
 		return;
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-10-15  3:02 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-13 23:35 [PATCH] Bluetooth: btintel_pcie: Fix NULL hdev dereference in debug register dump Chia-Lin Kao (AceLan)
2026-10-14  2:15 ` bluez.test.bot
2026-10-15  3:02 ` [PATCH] " AceLan Kao

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.