From 2cf81fc9505b148b1b70068303ea6ea4b1212403 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Lappetel=C3=A4inen?= Date: Fri, 25 Sep 2026 15:48:29 +0300 Subject: [PATCH] net/packet: prevent TX_RING byte count overflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tpacket_snd() drains every SEND_REQUEST frame in a TX ring and adds each valid packet length to the signed int len_sum. Userspace can recycle completed frames concurrently, so a single blocking send call is not bounded by the ring size. After enough successful transmissions len_sum wraps into the negative range. In particular, 65536 65535-byte frames followed by a 65007-byte frame produce 0xfffffdef, or -EIOCBQUEUED. sock_sendmsg_nosec() treats that as an impossible return and triggers a BUG. On systems configured to panic on oops, a CAP_NET_RAW holder can panic the host kernel. Stop before the next frame would make the byte count exceed INT_MAX. The positive short count leaves that frame pending for a later send call. A two-thread TPACKET_V2 reproducer triggered the BUG on an arm64 build of Linux 7.3-rc4. With this change, the same reproducer returned the expected positive short count without an oops. Fixes: 69e3c75f4d54 ("net: TX_RING and packet mmap") Cc: stable@vger.kernel.org Signed-off-by: Ilkka Lappeteläinen Reviewed-by: Willem de Bruijn Link: https://patch.msgid.link/20260925124829.6595-1-ilkka.lappetelainen@gmail.com Signed-off-by: Jakub Kicinski --- net/packet/af_packet.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 7c83e01526ed..8865c1a42667 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -2874,6 +2874,9 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) vnet_hdr.hdr_len); has_vnet_hdr = true; } + /* Prevent the byte count from wrapping into a negative errno */ + if (unlikely(tp_len > INT_MAX - len_sum)) + break; copylen = max_t(int, copylen, hard_header_len); skb = sock_alloc_send_skb(&po->sk, hlen + tlen + sizeof(struct sockaddr_ll) +