]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
usbnet: cap max_mtu for drivers without bind callback
authorLaurent Vivier <lvivier@redhat.com>
Fri, 31 Jul 2026 09:27:11 +0000 (11:27 +0200)
committerJakub Kicinski <kuba@kernel.org>
Wed, 5 Aug 2026 01:17:20 +0000 (18:17 -0700)
usbnet_probe() initializes max_mtu to ETH_MAX_MTU and only caps it
inside the if (info->bind) block. Drivers without a bind callback
never enter this block, so max_mtu stays at ETH_MAX_MTU.

QEMU's usb-net device (0x0525/0xa4a2) is claimed by the cdc_subset
driver which has no bind callback. The guest accepts any MTU from DHCP
(e.g. 65520 from passt), leading to TCP segments that exceed the
device's 2048-byte receive buffer and are silently dropped.

Initialize max_mtu to net->mtu at probe time and update it inside
the bind block.

Fixes: f77f0aee4da4 ("net: use core MTU range checking in USB NIC drivers")
Cc: jarod@redhat.com
Cc: stable@vger.kernel.org
Link: https://gitlab.com/qemu-project/qemu/-/issues/3268
Link: https://bugs.passt.top/show_bug.cgi?id=189
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Link: https://patch.msgid.link/20260731092711.857684-1-lvivier@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/usb/usbnet.c

index 25518635b7b72dc1e6b40ba082848091326c1560..a19ecf718f36a6c76cb684dfccaa2b4ed46142d0 100644 (file)
@@ -1794,7 +1794,7 @@ usbnet_probe(struct usb_interface *udev, const struct usb_device_id *prod)
         */
        dev->hard_mtu = net->mtu + net->hard_header_len;
        net->min_mtu = 0;
-       net->max_mtu = ETH_MAX_MTU;
+       net->max_mtu = net->mtu;
 
        net->netdev_ops = &usbnet_netdev_ops;
        net->watchdog_timeo = TX_TIMEOUT_JIFFIES;
@@ -1804,6 +1804,7 @@ usbnet_probe(struct usb_interface *udev, const struct usb_device_id *prod)
        // allow device-specific bind/init procedures
        // NOTE net->name still not usable ...
        if (info->bind) {
+               net->max_mtu = ETH_MAX_MTU;
                status = info->bind(dev, udev);
                if (status < 0)
                        goto out1;