[PATCH v2 1/3] Bluetooth: btmtk: drop zero-length ISO packets from endpoint padding
From: Chris Lu
Date: Thu Oct 15 2026 - 04:18:00 EST
The ISO interrupt IN endpoint delivers a fixed-size transfer that holds
one HCI ISO packet and zero-fills the remainder. That padding belongs to
the transfer rather than to the stream, so it has to be dropped instead of
reported to the host.
btmtk_recv_isopkt() keeps parsing it: the zero bytes read as an ISO header
with handle 0 and a Data_Total_Length of zero, and each one is passed to
hci_recv_frame() as a complete frame. A single transfer yields a long run
of them, which is what fills the HCI log with malformed ISO packets, and
iso_recv() drops the SDU it is reassembling whenever handle 0 belongs to a
live CIS/BIS.
A zero Data_Total_Length carries no ISO Data Load, so such a packet is
never part of the stream. The padding runs to the end of the transfer, so
stop parsing once one is seen.
This was observed on MT7925, but btmtk_recv_isopkt() is shared by every
MediaTek USB controller that supports ISO data.
Fixes: ceac1cb0259d ("Bluetooth: btusb: mediatek: add ISO data transmission functions")
Co-developed-by: Hao Qin <hao.qin@xxxxxxxxxxxx>
Signed-off-by: Hao Qin <hao.qin@xxxxxxxxxxxx>
Co-developed-by: Wenlong Tian <ot_wenlong.tian@xxxxxxxxxxxx>
Signed-off-by: Wenlong Tian <ot_wenlong.tian@xxxxxxxxxxxx>
Signed-off-by: Chris Lu <chris.lu@xxxxxxxxxxxx>
---
drivers/bluetooth/btmtk.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
index bdc85147b97f..869eb2176379 100644
--- a/drivers/bluetooth/btmtk.c
+++ b/drivers/bluetooth/btmtk.c
@@ -1201,6 +1201,19 @@ static int btmtk_recv_isopkt(struct hci_dev *hdev, void *buffer, int count)
/* Complete ISO header */
hci_skb_expect(skb) = __le16_to_cpu(dlen);
+ /* The interrupt endpoint zero-fills the remainder of
+ * each transfer, and that padding parses as a header
+ * with a zero Data_Total_Length. Such a packet carries
+ * no ISO Data Load at all and is never emitted by the
+ * controller, so stop parsing here rather than hand a
+ * bogus handle 0 packet to the stack.
+ */
+ if (!hci_skb_expect(skb)) {
+ kfree_skb(skb);
+ skb = NULL;
+ break;
+ }
+
if (skb_tailroom(skb) < hci_skb_expect(skb)) {
kfree_skb(skb);
skb = NULL;
--
2.45.2