Re: [PATCH net] ipv4: reject impossible oversized fragments at queue time
From: Eric Dumazet
Date: Fri Jul 17 2026 - 15:34:23 EST
On Fri, Jul 17, 2026 at 9:41 AM Yuxiang Yang
<yangyx22@xxxxxxxxxxxxxxxxxxxxx> wrote:
>
> 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.
I have a hard time understanding the issue.
This is an invalid packet, why should we add more bloat to
the kernel just to 'optimize' this case?
You understand that IP frags are unreliable no matter how hard we try
to 'fix' them, right ?
>
> 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@xxxxxxxxxxxxxxx
> Signed-off-by: Yuxiang Yang <yangyx22@xxxxxxxxxxxxxxxxxxxxx>
> ---
> 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
>