This aligns the ax88179_rx_fixup path with the latest linux upstream
version 61997271a5a7d ("net: usb: asix: ax88772: Increase phy_name
size").

Signed-off-by: Stefan Kerkmann <s.kerkm...@pengutronix.de>
---
 drivers/net/usb/ax88179_178a.c | 73 +++++++++++++++++++++++++++++-------------
 1 file changed, 51 insertions(+), 22 deletions(-)

diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
index 
0cf2635b77f86c9713dd5ed67d8ccf9bc30c45dd..78b5d943a4ecafab025ba3f8cc44293d16f31eb8
 100644
--- a/drivers/net/usb/ax88179_178a.c
+++ b/drivers/net/usb/ax88179_178a.c
@@ -435,46 +435,75 @@ static void ax88179_unbind(struct usbnet *dev)
 
 static int ax88179_rx_fixup(struct usbnet *dev, void *buf, int len)
 {
-       int pkt_cnt, frame_pos;
-       u32 rx_hdr;
-       u16 hdr_off;
+       u16 hdr_off, pkt_len, pkt_len_plus_padd;
+       u32 rx_hdr, hdr;
+       u8 *pos = buf;
        u32 *pkt_hdr;
+       int pkt_cnt;
 
        if (len == dev->rx_urb_size) {
-               dev_err(&dev->udev->dev, "broken package\n");
+               dev_err(&dev->udev->dev, "%s: broken packet\n", __func__);
                return 0;
        }
 
-       rx_hdr = get_unaligned_le32(buf + len - 4);
+       if (len < sizeof(rx_hdr)) {
+               dev_err(&dev->udev->dev, "%s: short packet\n", __func__);
+               return 0;
+       }
+
+       rx_hdr = get_unaligned_le32(buf + len - sizeof(rx_hdr));
+       pkt_cnt = lower_16_bits(rx_hdr);
+       hdr_off = upper_16_bits(rx_hdr);
+
+       if (pkt_cnt == 0)
+               return 0;
+
+       if ((pkt_cnt * sizeof(*pkt_hdr) + hdr_off) > (len - sizeof(rx_hdr))) {
+               dev_err(&dev->udev->dev,
+                       "%s: malformed metadata: pkt_cnt: %d hdr_off: %d len: 
%d\n",
+                       __func__, pkt_cnt, hdr_off, len);
+               return 0;
+       }
 
-       pkt_cnt = (u16)rx_hdr;
-       hdr_off = (u16)(rx_hdr >> 16);
        pkt_hdr = (u32 *)(buf + hdr_off);
 
-       frame_pos = 0;
+       /* Packets must not overlap the metadata array */
+       len = hdr_off;
 
-       while (pkt_cnt--) {
-               u16 pkt_len;
-               u32 hdr = le32_to_cpup(pkt_hdr);
+       for (; pkt_cnt > 0; pkt_cnt--, pkt_hdr++) {
+               hdr = le32_to_cpup(pkt_hdr);
+               pkt_len = upper_16_bits(hdr) & GENMASK(12, 0);
+               pkt_len_plus_padd = (pkt_len + 7) & GENMASK(15, 3);
 
-               pkt_len = (hdr >> 16) & 0x1fff;
+               /* Skip dummy header used for alignment */
+               if (pkt_len == 0)
+                       continue;
+
+               if (pkt_len_plus_padd > len) {
+                       dev_dbg(&dev->udev->dev,
+                               "%s: packet too large: %d > %d\n", __func__,
+                               pkt_len_plus_padd, len);
+                       return 0;
+               }
 
                /* Check CRC or runt packet */
-               if ((hdr & AX_RXHDR_CRC_ERR) ||
-                   (hdr & AX_RXHDR_DROP_ERR)) {
-                       pkt_hdr++;
+               if ((hdr & (AX_RXHDR_CRC_ERR | AX_RXHDR_DROP_ERR)) ||
+                   pkt_len < sizeof(u16) + ETH_HLEN) {
+                       dev_dbg(&dev->udev->dev,
+                               "%s: dropping packet: hdr: 0x%08x len: %d\n",
+                               __func__, hdr, pkt_len);
+                       pos += pkt_len_plus_padd;
+                       len -= pkt_len_plus_padd;
                        continue;
                }
 
-               frame_pos += 2;
+               dev_dbg(&dev->udev->dev, "%s: loop: frame_pos: %td len: %d\n",
+                       __func__, pos - (u8 *)buf, pkt_len);
 
-               dev_dbg(&dev->udev->dev, "%s: loop: frame_pos: %d len: %d\n",
-                       __func__, frame_pos, pkt_len);
+               net_receive(&dev->edev, pos + sizeof(u16), pkt_len);
 
-               net_receive(&dev->edev, buf + frame_pos, pkt_len);
-
-               pkt_hdr++;
-               frame_pos += ((pkt_len + 7) & 0xfff8) - 2;
+               pos += pkt_len_plus_padd;
+               len -= pkt_len_plus_padd;
        }
 
        return 0;

-- 
2.39.5


Reply via email to