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@vger.kernel.org Assisted-by: Claude (Anthropic) Signed-off-by: Aamir Ahmed --- 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