Jiri Slaby 7a187a
From: Szymon Heidrich <szymon.heidrich@gmail.com>
Jiri Slaby 7a187a
Date: Sat, 18 Mar 2023 10:25:52 +0100
Jiri Slaby 7a187a
Subject: [PATCH] net: usb: lan78xx: Limit packet length to skb->len
Jiri Slaby 7a187a
References: bsc#1012628
Jiri Slaby 7a187a
Patch-mainline: 6.2.9
Jiri Slaby 7a187a
Git-commit: 7f247f5a2c18b3f21206cdd51193df4f38e1b9f5
Jiri Slaby 7a187a
Jiri Slaby 7a187a
[ Upstream commit 7f247f5a2c18b3f21206cdd51193df4f38e1b9f5 ]
Jiri Slaby 7a187a
Jiri Slaby 7a187a
Packet length retrieved from descriptor may be larger than
Jiri Slaby 7a187a
the actual socket buffer length. In such case the cloned
Jiri Slaby 7a187a
skb passed up the network stack will leak kernel memory contents.
Jiri Slaby 7a187a
Jiri Slaby 7a187a
Additionally prevent integer underflow when size is less than
Jiri Slaby 7a187a
ETH_FCS_LEN.
Jiri Slaby 7a187a
Jiri Slaby 7a187a
Fixes: 55d7de9de6c3 ("Microchip's LAN7800 family USB 2/3 to 10/100/1000 Ethernet device driver")
Jiri Slaby 7a187a
Signed-off-by: Szymon Heidrich <szymon.heidrich@gmail.com>
Jiri Slaby 7a187a
Signed-off-by: David S. Miller <davem@davemloft.net>
Jiri Slaby 7a187a
Signed-off-by: Sasha Levin <sashal@kernel.org>
Jiri Slaby 7a187a
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Jiri Slaby 7a187a
---
Jiri Slaby 7a187a
 drivers/net/usb/lan78xx.c | 18 +++++++++++++++++-
Jiri Slaby 7a187a
 1 file changed, 17 insertions(+), 1 deletion(-)
Jiri Slaby 7a187a
Jiri Slaby 7a187a
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
Jiri Slaby 7a187a
index 06848889..c458c030 100644
Jiri Slaby 7a187a
--- a/drivers/net/usb/lan78xx.c
Jiri Slaby 7a187a
+++ b/drivers/net/usb/lan78xx.c
Jiri Slaby 7a187a
@@ -3579,13 +3579,29 @@ static int lan78xx_rx(struct lan78xx_net *dev, struct sk_buff *skb,
Jiri Slaby 7a187a
 		size = (rx_cmd_a & RX_CMD_A_LEN_MASK_);
Jiri Slaby 7a187a
 		align_count = (4 - ((size + RXW_PADDING) % 4)) % 4;
Jiri Slaby 7a187a
 
Jiri Slaby 7a187a
+		if (unlikely(size > skb->len)) {
Jiri Slaby 7a187a
+			netif_dbg(dev, rx_err, dev->net,
Jiri Slaby 7a187a
+				  "size err rx_cmd_a=0x%08x\n",
Jiri Slaby 7a187a
+				  rx_cmd_a);
Jiri Slaby 7a187a
+			return 0;
Jiri Slaby 7a187a
+		}
Jiri Slaby 7a187a
+
Jiri Slaby 7a187a
 		if (unlikely(rx_cmd_a & RX_CMD_A_RED_)) {
Jiri Slaby 7a187a
 			netif_dbg(dev, rx_err, dev->net,
Jiri Slaby 7a187a
 				  "Error rx_cmd_a=0x%08x", rx_cmd_a);
Jiri Slaby 7a187a
 		} else {
Jiri Slaby 7a187a
-			u32 frame_len = size - ETH_FCS_LEN;
Jiri Slaby 7a187a
+			u32 frame_len;
Jiri Slaby 7a187a
 			struct sk_buff *skb2;
Jiri Slaby 7a187a
 
Jiri Slaby 7a187a
+			if (unlikely(size < ETH_FCS_LEN)) {
Jiri Slaby 7a187a
+				netif_dbg(dev, rx_err, dev->net,
Jiri Slaby 7a187a
+					  "size err rx_cmd_a=0x%08x\n",
Jiri Slaby 7a187a
+					  rx_cmd_a);
Jiri Slaby 7a187a
+				return 0;
Jiri Slaby 7a187a
+			}
Jiri Slaby 7a187a
+
Jiri Slaby 7a187a
+			frame_len = size - ETH_FCS_LEN;
Jiri Slaby 7a187a
+
Jiri Slaby 7a187a
 			skb2 = napi_alloc_skb(&dev->napi, frame_len);
Jiri Slaby 7a187a
 			if (!skb2)
Jiri Slaby 7a187a
 				return 0;
Jiri Slaby 7a187a
-- 
Jiri Slaby 7a187a
2.35.3
Jiri Slaby 7a187a