[PATCH net 1/5] net: wwan: iosm: validate the MUX DL block length

From
Fang Xieyan <hidden>
Date
2026-11-12 12:52:09
Also in
lkml, stable
Reply to
Fang Xieyan, 2026-11-12
The received length of a DL MUX block is supplied by the device and can
be shorter than the header its signature advertises. ipc_mux_dl_decode()
reads the four byte signature and then lets the decoders index their
header structures without checking skb->len, so a short block makes the
driver decode past the received data.

Check the signature before reading it, and check the header size of the
ADGH, FCTH and CMDH branches before dispatching to their decoders. The
ADB branch already validates its own headers, and the ACBH branch is
covered by the bounds checks of its command chain walk. A block too
short to carry its signature is dropped on the way to the single free.

Fixes: 9413491e20e1 ("net: iosm: encode or decode datagram")
Cc: <redacted>
Reviewed-by: Guanglei Zhu <redacted>
Signed-off-by: Fang Xieyan <redacted>
---
 drivers/net/wwan/iosm/iosm_ipc_mux_codec.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
diff --git a/drivers/net/wwan/iosm/iosm_ipc_mux_codec.c b/drivers/net/wwan/iosm/iosm_ipc_mux_codec.c
index 0bbd41263cc2..5c33171ca701 100644
--- a/drivers/net/wwan/iosm/iosm_ipc_mux_codec.c
+++ b/drivers/net/wwan/iosm/iosm_ipc_mux_codec.c
@@ -696,6 +696,11 @@ void ipc_mux_dl_decode(struct iosm_mux *ipc_mux, struct sk_buff *skb)
 	if (!skb->data)
 		return;
 
+	if (skb->len < sizeof(signature)) {
+		dev_err(ipc_mux->dev, "invalid MUX block length %u", skb->len);
+		goto free_skb;
+	}
+
 	/* Decode the MUX header type. */
 	signature = le32_to_cpup((__le32 *)skb->data);
 
@@ -704,15 +709,24 @@ void ipc_mux_dl_decode(struct iosm_mux *ipc_mux, struct sk_buff *skb)
 		mux_dl_adb_decode(ipc_mux, skb);
 		break;
 	case IOSM_AGGR_MUX_SIG_ADGH:
+		if (skb->len < sizeof(struct mux_adgh))
+			break;
+
 		ipc_mux_dl_adgh_decode(ipc_mux, skb);
 		break;
 	case MUX_SIG_FCTH:
+		if (skb->len < sizeof(struct ipc_mem_lite_gen_tbl))
+			break;
+
 		ipc_mux_dl_fcth_decode(ipc_mux, skb->data);
 		break;
 	case IOSM_AGGR_MUX_SIG_ACBH:	/* Aggregated Command Block Header */
 		ipc_mux_dl_acb_decode(ipc_mux, skb);
 		break;
 	case MUX_SIG_CMDH:
+		if (skb->len < offsetof(struct mux_lite_cmdh, param))
+			break;
+
 		ipc_mux_dl_cmd_decode(ipc_mux, skb);
 		break;
 
@@ -720,6 +734,7 @@ void ipc_mux_dl_decode(struct iosm_mux *ipc_mux, struct sk_buff *skb)
 		dev_err(ipc_mux->dev, "invalid ABH signature");
 	}
 
+free_skb:
 	ipc_pcie_kfree_skb(ipc_mux->pcie, skb);
 }
 
-- 
2.50.1
Thread (6 messages) 6 messages, 1 author, last reply 1d ago
Keyboard shortcuts
hback out one level
jnext message in thread / next series-diff position
kprevious message in thread / previous series-diff position
ldrill in
Escclose help / fold thread tree
?toggle this help