Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH] Bluetooth: btusb_qcom: check reassembly bounds and pull results
@ 2026-11-08 22:32 Noah Weinberger
  2026-11-08 23:43 ` bluez.test.bot
  0 siblings, 1 reply; 2+ messages in thread
From: Noah Weinberger @ 2026-11-08 22:32 UTC (permalink / raw)
  To: marcel@holtmann.org, luiz.dentz@gmail.com
  Cc: linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org

Hello,

Three hardening gaps in the new Qualcomm multi-subsystem transport, all
of them patterns the sibling paths already handle:

 1. btusb_qcom_recv_intr() computes the expected payload length from
    the device-supplied header and re-enters the fill loop without
    checking it against the skb tailroom. The bulk path
    (btusb_qcom_recv_bulk) rejects hci_skb_expect(skb) >
    QPERI_MAX_FRAME_SIZE - skb->len; the interrupt path relies solely on
    the u8 width of the two length fields and a three-byte margin.
 2. btqcom_recv_vendor_pkt() dereferences skb_pull_data(skb, 1)
    without a NULL check.
 3. btusb_qcom_send_frame() does the same for vendor packets on the TX
    path.

None of these is reachable with the current in-tree producers (the
empty-vendor-packet invariant is established several call-hops away),
so this is regression protection for brand-new code rather than a live
bug fix. The patch mirrors the bulk-path check and adds the NULL
checks.

Affected version/commit: mainline fa4ad798f6f681031775266044ba1b0cf3c670bd (v7.4-rc1, 2026-11-07), drivers/bluetooth/btusb_qcom.c:4387-4462 (recv_intr), 2624-2628 (recv_vendor_pkt), 4258-4262 (send_frame).
New driver merged in this window.

This was found during an assisted (AI-supported) static source review of
mainline fa4ad798f6f681031775266044ba1b0cf3c670bd (v7.4-rc1, 2026-11-07); every code path cited below was re-verified by the
reporter against that tree. The patch below has NOT been compiled and has
NOT been runtime tested, and no reproducer was produced - the triggering
conditions are described above instead. Please treat this as a report for
verification rather than a battle-tested fix.

Reported-by: Noah Weinberger <noahweinberger2003@proton.me>
---
diff --git a/drivers/bluetooth/btusb_qcom.c b/drivers/bluetooth/btusb_qcom.c
index cc4cfcd..3c41e60 100644
--- a/drivers/bluetooth/btusb_qcom.c
+++ b/drivers/bluetooth/btusb_qcom.c
@@ -2623,7 +2623,13 @@ out_free_skb:
 /* Implements hdev->recv_vendor_pkt(). */
 static void btqcom_recv_vendor_pkt(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	hci_skb_pkt_type(skb) = *(const u8 *)skb_pull_data(skb, 1);
+	const u8 *pkt = skb_pull_data(skb, 1);
+
+	if (!pkt) {
+		kfree_skb(skb);
+		return;
+	}
+	hci_skb_pkt_type(skb) = *pkt;
 
 	switch (hci_skb_pkt_type(skb)) {
 	case QPERI_EVENT_PKT:
@@ -4257,8 +4263,13 @@ int btusb_qcom_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 	pkt_type = hci_skb_pkt_type(skb);
 	is_vendor = pkt_type == HCI_VENDOR_PKT;
 	/* an empty vendor packet has no path to reach here */
-	if (is_vendor)
-		hci_skb_pkt_type(skb) = *(const u8 *)skb_pull_data(skb, 1);
+	if (is_vendor) {
+		const u8 *pkt = skb_pull_data(skb, 1);
+
+		if (!pkt)
+			return -EILSEQ;
+		hci_skb_pkt_type(skb) = *pkt;
+	}
 
 	pkt_type = hci_skb_pkt_type(skb);
 	need_lock = pkt_type == HCI_COMMAND_PKT ||
@@ -4438,5 +4449,13 @@ struct sk_buff *btusb_qcom_recv_intr(struct hci_dev *hdev, struct sk_buff *skb,
 		else if (pkt_type == HCI_EVENT_PKT)
 			hci_skb_expect(skb) = hci_event_hdr(skb)->plen;
 
+		if (hci_skb_expect(skb) >
+		    QPERI_MAX_EVENT_SIZE - skb->len) {
+			dev_kfree_skb_irq(skb);
+			skb = NULL;
+			*err = -EILSEQ;
+			break;
+		}
+
 		if (hci_skb_expect(skb))
 			continue;


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

end of thread, other threads:[~2026-11-08 23:43 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-08 22:32 [PATCH] Bluetooth: btusb_qcom: check reassembly bounds and pull results Noah Weinberger
2026-11-08 23:43 ` bluez.test.bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox