]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: usb: cdc-phonet: fix skb frags[] overflow in rx_complete()
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 11 Apr 2026 11:01:35 +0000 (13:01 +0200)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 14 Apr 2026 10:05:01 +0000 (12:05 +0200)
A malicious USB device claiming to be a CDC Phonet modem can overflow
the skb_shared_info->frags[] array by sending an unbounded sequence of
full-page bulk transfers.

Drop the skb and increment the length error when the frag limit is
reached.  This matches the same fix that commit f0813bcd2d9d ("net:
wwan: t7xx: fix potential skb->frags overflow in RX path") did for the
t7xx driver.

Cc: Andrew Lunn <andrew+netdev@lunn.ch>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: stable <stable@kernel.org>
Assisted-by: gregkh_clanker_t1000
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Link: https://patch.msgid.link/2026041134-dreamboat-buddhism-d1ec@gregkh
Fixes: 87cf65601e17 ("USB host CDC Phonet network interface driver")
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/usb/cdc-phonet.c

index ad5121e9cf5d6fe5dfcaa979e33b23ffc5706c63..165650ecef649fb9c8fcd098fbcffa004be90f74 100644 (file)
@@ -157,11 +157,16 @@ static void rx_complete(struct urb *req)
                                                PAGE_SIZE);
                                page = NULL;
                        }
-               } else {
+               } else if (skb_shinfo(skb)->nr_frags < MAX_SKB_FRAGS) {
                        skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
                                        page, 0, req->actual_length,
                                        PAGE_SIZE);
                        page = NULL;
+               } else {
+                       dev_kfree_skb_any(skb);
+                       pnd->rx_skb = NULL;
+                       skb = NULL;
+                       dev->stats.rx_length_errors++;
                }
                if (req->actual_length < PAGE_SIZE)
                        pnd->rx_skb = NULL; /* Last fragment */