[PATCH] wifi: mt76: mt7996: validate TLV length in mt7996_mcu_ie_countdown()

From: Aamir Ahmed

Date: Mon Sep 07 2026 - 05:08:10 EST


mt7996_mcu_ie_countdown() iterates over TLV entries in the countdown
event but only checks for a non-zero tlv->len. A malformed event with
a TLV length smaller than the 4-byte TLV header advances the cursor by
less than a header size, causing misaligned reads on subsequent
iterations. A TLV whose declared length exceeds the remaining buffer
is also not caught, so the cursor can overshoot the end.

This is the same class of bug fixed for mt7925 in
commit fc7801b7f11d ("wifi: mt76: mt7925: fix infinite loop in UNI
event TLV parsing").

Fix by validating that each TLV length is at least sizeof(*tlv) and
does not exceed the remaining buffer, and that it is large enough to
contain the countdown notify payload before dereferencing.

Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: Claude (Anthropic)
Signed-off-by: Aamir Ahmed <elb12345@xxxxxxxxxxxxx>
---
drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
index cd7587ce5b8a6..f74c4b0bda3c1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
@@ -497,10 +497,18 @@ mt7996_mcu_ie_countdown(struct mt7996_dev *dev, struct sk_buff *skb)

tail = skb->data + skb->len;
data += sizeof(*hdr);
- while (data + sizeof(*tlv) < tail && le16_to_cpu(tlv->len)) {
+ while (data + sizeof(*tlv) <= tail) {
+ u16 tag_len = le16_to_cpu(tlv->len);
+
+ if (tag_len < sizeof(*tlv) || data + tag_len > tail)
+ break;
+
event = (struct mt7996_mcu_countdown_notify *)tlv->data;

- cdata.omac_idx = event->omac_idx;
+ if (tag_len >= sizeof(*tlv) + sizeof(*event))
+ cdata.omac_idx = event->omac_idx;
+ else
+ break;

switch (le16_to_cpu(tlv->tag)) {
case UNI_EVENT_IE_COUNTDOWN_CSA:
@@ -517,7 +525,7 @@ mt7996_mcu_ie_countdown(struct mt7996_dev *dev, struct sk_buff *skb)
break;
}

- data += le16_to_cpu(tlv->len);
+ data += tag_len;
tlv = (struct tlv *)data;
}
}
--
2.43.0