[PATCH wireless-next v2] wifi: mm81x: validate packet length in mm81x_yaps_read_pkt()

DORMANTno replies

From: Aamir Ahmed <hidden>
Date: 2026-09-12 11:09:41
Subsystem: morse micro mm81x wireless driver, networking drivers (wireless), the rest · Maintainers: Lachlan Hodges, Dan Callaghan, Johannes Berg, Linus Torvalds

mm81x_yaps_read_pkt() reads struct mm81x_skb_hdr from the start of an
skb whose length comes from the YAPS delimiter, without checking that
the skb holds the header. The length the header claims,
sizeof(*hdr) + hdr->offset + hdr->len, is not checked against skb->len
either: mm81x_skbq_validate_checksum() sizes its walk of the skb from
hdr->len, skb_trim() cannot grow the skb to the claimed length, and
mm81x_skbq_dispatch_work() then pulls sizeof(*hdr) + hdr->offset from
an skb that may be shorter than that.

Validate skb->len against sizeof(*hdr) before the header is read, and
the header-claimed length against skb->len right after the sync check,
before the checksum is validated and the packet is trimmed and queued.

Assisted-by: LLM
Fixes: b1906cea00b0 ("wifi: mm81x: add mm81x Wi-Fi HaLow driver")
Signed-off-by: Aamir Ahmed <redacted>
---
v2:
  - check the header-claimed length right after the sync check, before
    mm81x_skbq_validate_checksum() walks the skb; v1 checked it after
    that call (Sashiko)
  - move the existing skb_len computation up to the new check
  - return -EIO like the sync and channel checks instead of -EINVAL,
    and word the errors like the existing ones
  - commit message rewritten
  - Assisted-by: LLM added, before Fixes:, and wireless-next named in
    the subject (Lachlan, on the n_channels patch)
  - no Cc: stable, the driver is only in v7.3-rc; recipients from
    get_maintainer
v1: https://lore.kernel.org/linux-wireless/AS8P251MB0001B650C31E9F37C3B7907BC8B32@AS8P251MB0001.EURP251.PROD.OUTLOOK.COM/ (local)

The other items Sashiko raised on v1 - mm81x_skbq_validate_checksum()
reading frame_control past the header of a header-only data packet and
ignoring hdr->offset, and the skb leak on the -ENOMEM path of
mm81x_yaps_hw_read_pkts() - are left for separate patches. The command
response length is validated by "wifi: mm81x: validate response length
in mm81x_cmd_resp_process()", sent alongside.

Compile-tested only (W=1 and sparse on the base-commit below); I have
no mm81x hardware.

 drivers/net/wireless/morsemicro/mm81x/yaps.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/morsemicro/mm81x/yaps.c b/drivers/net/wireless/morsemicro/mm81x/yaps.c
index e98a2a587..ba03bd9b3 100644
--- a/drivers/net/wireless/morsemicro/mm81x/yaps.c
+++ b/drivers/net/wireless/morsemicro/mm81x/yaps.c
@@ -147,6 +147,13 @@ static int mm81x_yaps_read_pkt(struct mm81x_yaps *yaps, struct sk_buff *skb)
 
 	__skb_queue_head_init(&skbq);
 
+	if (skb->len < sizeof(*hdr)) {
+		dev_err(mors->dev, "packet length error [%u < %zu]", skb->len,
+			sizeof(*hdr));
+		ret = -EIO;
+		goto exit_return_page;
+	}
+
 	hdr = (struct mm81x_skb_hdr *)skb->data;
 	if (hdr->sync != MM81X_SKB_HEADER_SYNC) {
 		dev_err(mors->dev, "sync value error [0xAA:%d], hdr.len %d",
@@ -155,6 +162,14 @@ static int mm81x_yaps_read_pkt(struct mm81x_yaps *yaps, struct sk_buff *skb)
 		goto exit_return_page;
 	}
 
+	skb_len = sizeof(*hdr) + hdr->offset + le16_to_cpu(hdr->len);
+	if (skb_len > skb->len) {
+		dev_err(mors->dev, "hdr length error [%d > %u]", skb_len,
+			skb->len);
+		ret = -EIO;
+		goto exit_return_page;
+	}
+
 	if (yaps->mors->hif.validate_skb_checksum &&
 	    !mm81x_skbq_validate_checksum(skb->data)) {
 		dev_dbg(yaps->mors->dev,
@@ -185,7 +200,6 @@ static int mm81x_yaps_read_pkt(struct mm81x_yaps *yaps, struct sk_buff *skb)
 		goto exit_return_page;
 	}
 
-	skb_len = sizeof(*hdr) + hdr->offset + le16_to_cpu(hdr->len);
 	skb_bytes_remaining = mm81x_skbq_space(mq);
 
 	if (skb_len > skb_bytes_remaining) {
base-commit: 13e51269b6656768dc595ed6025e4974f2026543
-- 
2.43.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help