Re: [PATCH] net: gro: avoid parsing headers from shared fragments
From: Eric Dumazet
Date: Fri Oct 30 2026 - 03:08:21 EST
Le ven. 30 oct. 2026 à 05:22, Kyle Zeng <kylebot@xxxxxxxxxx> a écrit :
>
> When an skb has an empty linear head, skb_gro_reset_offset() can expose
> the first page fragment directly to GRO header parsers. For a
> SKBFL_SHARED_FRAG skb, those bytes may still be writable through a file
> mapping. Headers validated during receive can therefore differ from the
> headers later copied into the linear head and used during completion.
>
> For example, changing an IPv6 destination-options length between the
> short and full header fetches in ipv6_gro_pull_exthdrs() can make
> ipv6_gro_complete() pass an out-of-bounds offset to udp6_gro_complete().
> This is reachable with an ordinary TCP GSO skb containing spliced file
> data, without an skb zerocopy destructor or a second GRO packet.
"ordinary TCP GSO skb" ???
I do not see how a TCP GSO skb reaches skb_gro_reset_offset() with
skb_headlen() == 0 : TCP always builds its headers in skb->head.
My guess is that you need a decap step first (gro_cells after a tunnel
pulled the outer headers), so that the inner headers come from spliced
pages and start at frags[0].
Please describe the exact path in the changelog, and send me the
reproducer privately.
>
> Keep the direct-fragment fast path disabled for skbs with externally
> writable fragments. With an empty linear head, frag0_len remains zero,
> so skb_gro_header_slow() pulls each required header into the linear head
> before it is inspected. Subsequent pulls preserve the already validated
> prefix. This covers both gro_receive_skb() and napi_gro_frags() while
> leaving the existing linear-head and private-fragment fast paths alone.
>
> Signed-off-by: Kyle Zeng <kylebot@xxxxxxxxxx>
> ---
> I have a reproducer for this issue and can share via DM
The fix itself looks fine to me, but for v2 please:
- Target the net tree ([PATCH net]).
- Add a Fixes: tag. This is requested for net patches.
- Tell us how the bug was found (tool, LLM, manual audit...), as the
netdev bot asked.
Thanks.