[PATCH wireless-next 3/4] wifi: mm81x: bound the .fw_info TLV walk
From: Linmao Li
Date: Wed Aug 12 2026 - 02:13:18 EST
mm81x_fw_parse_info() only checks that a TLV header starts before the
end of the section, so a header that straddles the end is read anyway,
and MM81X_FW_INFO_TLV_BCF_ADDR reads its four-byte value without looking
at the TLV length at all. The BCF address can come from whatever
follows the section.
Walk by remaining length, and only take the address when the value is
really there.
Fixes: b1906cea00b0 ("wifi: mm81x: add mm81x Wi-Fi HaLow driver")
Signed-off-by: Linmao Li <lilinmao@xxxxxxxxxx>
---
drivers/net/wireless/morsemicro/mm81x/fw.c | 24 ++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/morsemicro/mm81x/fw.c b/drivers/net/wireless/morsemicro/mm81x/fw.c
index a2cb97cefc4e9..d2fba42e53627 100644
--- a/drivers/net/wireless/morsemicro/mm81x/fw.c
+++ b/drivers/net/wireless/morsemicro/mm81x/fw.c
@@ -54,21 +54,29 @@ static int mm81x_fw_get_header(const u8 *data, Elf32_Ehdr *ehdr)
static void mm81x_fw_parse_info(struct mm81x *mors, const u8 *data, int length)
{
- const struct mm81x_fw_info_tlv *tlv =
- (const struct mm81x_fw_info_tlv *)data;
+ const u8 *end = data + length;
+ const u8 *pos = data;
+
+ while (end - pos >= (ptrdiff_t)sizeof(struct mm81x_fw_info_tlv)) {
+ const struct mm81x_fw_info_tlv *tlv =
+ (const struct mm81x_fw_info_tlv *)pos;
+ u16 tlv_len = le16_to_cpu(tlv->length);
+
+ pos = tlv->val;
+ if (tlv_len > end - pos)
+ break;
- while ((u8 *)tlv < (data + length)) {
switch (le16_to_cpu(tlv->type)) {
case MM81X_FW_INFO_TLV_BCF_ADDR:
- mors->bcf_address = get_unaligned_le32(tlv->val);
+ if (tlv_len >= sizeof(__le32))
+ mors->bcf_address =
+ get_unaligned_le32(tlv->val);
break;
default:
break;
}
- tlv = (const struct mm81x_fw_info_tlv *)((u8 *)tlv +
- le16_to_cpu(
- tlv->length) +
- sizeof(*tlv));
+
+ pos += tlv_len;
}
}
--
2.25.1