ipc_mux_dl_adgh_decode() takes adgh->length from the device and hands
adgh_len - packet_offset to the network stack as the payload size of the
cloned skb, without bounding adgh_len at all. When the device reports a
datagram shorter than the ADGH header plus its negotiated padding, the
subtraction wraps to a huge u32, skb_trim() refuses the length and keeps
the clone unchanged, and the stack gets every byte left in the block
instead of the declared payload. A length beyond skb->len is nonsense
that the driver passes on as well.
Require the datagram length to cover packet_offset and to fit into
skb->len, and drop the block otherwise.
Fixes: c34ca4f32c24 ("net: wwan: iosm: fix incorrect skb length")
Cc: <redacted>
Reviewed-by: Guanglei Zhu <redacted>
Signed-off-by: Fang Xieyan <redacted>
---
drivers/net/wwan/iosm/iosm_ipc_mux_codec.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/net/wwan/iosm/iosm_ipc_mux_codec.c b/drivers/net/wwan/iosm/iosm_ipc_mux_codec.c
index 5c33171ca701..b573067a366f 100644
--- a/drivers/net/wwan/iosm/iosm_ipc_mux_codec.c
+++ b/drivers/net/wwan/iosm/iosm_ipc_mux_codec.c
@@ -473,6 +473,15 @@ static void ipc_mux_dl_adgh_decode(struct iosm_mux *ipc_mux,
if_id += ipc_mux->wwan_q_offset;
adgh_len = le16_to_cpu(adgh->length);
+ /* The device supplied length bounds the datagram. It has to
+ * cover packet_offset and fit into the received block.
+ */
+ if (adgh_len < packet_offset || adgh_len > skb->len) {
+ dev_err(ipc_mux->dev, "invalid ADGH length %u, skb len %u",
+ adgh_len, skb->len);
+ return;
+ }
+
/* Pass the packet to the netif layer */
rc = ipc_mux_net_receive(ipc_mux, if_id, wwan, packet_offset,
adgh->service_class, skb,--
2.50.1