mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Yuxiang Yang <yangyx22@mails.tsinghua.edu.cn>
To: netdev@vger.kernel.org
Cc: dsahern@kernel.org, idosch@nvidia.com, davem@davemloft.net,
	edumazet@google.com, kuba@kernel.org, pabeni@redhat.com,
	horms@kernel.org, linux-kernel@vger.kernel.org,
	Yuxiang Yang <yangyx22@mails.tsinghua.edu.cn>,
	stable@vger.kernel.org,
	Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>,
	Ao Wang <wangao@seu.edu.cn>, Xuewei Feng <fengxw06@126.com>,
	Qi Li <qli01@tsinghua.edu.cn>, Ke Xu <xuke@tsinghua.edu.cn>,
	yyxroy22@gmail.com
Subject: [PATCH net] ipv4: reject impossible oversized fragments at queue time
Date: Fri, 17 Jul 2026 07:41:09 +0000	[thread overview]
Message-ID: <20260717074109.686170-1-yangyx22@mails.tsinghua.edu.cn> (raw)

ip_frag_queue() computes each incoming fragment's end offset and may
store it in qp->q.len without checking that the fragment can fit within
the 65535 byte IPv4 datagram limit, even with the minimum IPv4 header.
The only 65535 byte check lives later in ip_frag_reasm(), after the
fragment has already been accepted into the reassembly queue and has
updated its state.

A fragment whose end offset exceeds 65535 minus the minimum 20-byte IPv4
header cannot be part of any valid IPv4 datagram. Letting it update
qp->q.len leaves the shared reassembly queue with an impossible expected
length. A later legitimate two-fragment datagram sharing that key can no
longer complete reassembly and is not delivered.

This was verified at runtime on Linux 6.12.93-0-virt. A same-key
oversized-fragment injection (offset 65528, payload 8, end 65536) drove
legitimate two-fragment UDP delivery from 8/8 to 0/8, while a cross-ID
control stayed at 8/8.

With this change applied to net main, the same-key test delivered 8/8.
A valid 65535-byte datagram with a 20-byte header was also delivered with
both in-order and reverse-order fragments; its 65507-byte UDP payload
was intact in both cases.

Add a per-fragment bound check in ip_frag_queue() right after computing
end and before any qp->q.len update or skb insertion. IPv4 always needs
at least a struct iphdr, so an end offset greater than IP_MAX_MTU minus
sizeof(struct iphdr) cannot fit in any valid IPv4 datagram. Use that
minimum-header bound rather than the current fragment's IHL because
fragments may arrive out of order and the first fragment may carry
non-copied options that later fragments lack. The existing check in
ip_frag_reasm() continues to validate the final length against the
actual header length of the first fragment.

Drop only the invalid skb so an existing queue for the same key remains
intact.

The issue was found by Yuxiang Yang, Yizhou Zhao, Ao Wang, Xuewei Feng,
Qi Li, and Ke Xu, with assistance from GLM-5.2 by Z.ai.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Yuxiang Yang <yangyx22@mails.tsinghua.edu.cn>
---
 net/ipv4/ip_fragment.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index c790d2f49..32e5240a5 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -291,6 +291,8 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb, int *refs)
 	/* Determine the position of this fragment. */
 	end = offset + skb->len - skb_network_offset(skb) - ihl;
 	err = -EINVAL;
+	if (end > IP_MAX_MTU - sizeof(struct iphdr))
+		goto err;
 
 	/* Is this the final fragment? */
 	if ((flags & IP_MF) == 0) {
-- 
2.34.1


             reply	other threads:[~2026-07-17  7:41 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-17  7:41 Yuxiang Yang [this message]
2026-07-17 19:33 ` Eric Dumazet

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260717074109.686170-1-yangyx22@mails.tsinghua.edu.cn \
    --to=yangyx22@mails.tsinghua.edu.cn \
    --cc=davem@davemloft.net \
    --cc=dsahern@kernel.org \
    --cc=edumazet@google.com \
    --cc=fengxw06@126.com \
    --cc=horms@kernel.org \
    --cc=idosch@nvidia.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=qli01@tsinghua.edu.cn \
    --cc=stable@vger.kernel.org \
    --cc=wangao@seu.edu.cn \
    --cc=xuke@tsinghua.edu.cn \
    --cc=yyxroy22@gmail.com \
    --cc=zhaoyz24@mails.tsinghua.edu.cn \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox