Re: [PATCH net] fou: ensure GUE headers have enough headroom

Antoine Tenart <[email protected]>
Newsgroups gmane.linux.network,gmane.linux.kernel,gmane.linux.kernel.stable
Message-ID <anHVNZdaVfxzbXCO@kwain>
On Sat, Aug 01, 2026 at 02:01:15PM +0800, Chengfeng Ye wrote:
> ipgre_changelink() installs GUE encapsulation before it publishes the
> new GRE header length and updates dev->needed_headroom.  The transmit
> path does not serialize with RTNL, so it can interleave as follows:
> 
>   CPU 0 (ipgre_changelink)        CPU 1 (ipgre_xmit)
>   install GUE encapsulation
>                                   reserve the old needed_headroom
>   publish larger GRE flags
>   update tunnel->tun_hlen
>                                   push the larger GRE header
>                                   push the GUE and UDP headers
>   update dev->needed_headroom
> 
> With REMCSUM, the new layout can push 16 bytes of GRE and 20 bytes of
> GUE/UDP headers into an skb with only 32 bytes of actual headroom.  The
> final UDP push writes four bytes before skb->head.
> 
> With the update window widened, the kernel reported:
> 
>   skbuff: skb_under_panic: ... len:128 put:8 ... dev:gre0poc
>   kernel BUG at net/core/skbuff.c:214!
>   Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI
>   Call Trace:
>    skb_push
>    fou_build_udp
>    gue_build_header
>    ip_tunnel_xmit
>    __gre_xmit
>    ipgre_xmit
> 
> Make __gue_build_header() ensure space for both the GUE header it is
> about to push and the UDP header that follows.  On normally sized skbs
> the check is a no-op.  If configuration changes race with transmission,
> skb_cow_head() expands the head before either GUE write, or returns an
> error without modifying the packet.
> 
> Fixes: dd9d598c6657 ("ip_gre: add the support for i/o_flags update via netlink")
> Cc: [email protected]
> Assisted-by: Codex:gpt-5
> Signed-off-by: Chengfeng Ye <[email protected]>
> ---
>  net/ipv4/fou_core.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/net/ipv4/fou_core.c b/net/ipv4/fou_core.c
> index ab09dfcdecbd..8cf0d43acb41 100644
> --- a/net/ipv4/fou_core.c
> +++ b/net/ipv4/fou_core.c
> @@ -980,6 +980,8 @@ int __gue_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
>  						skb, 0, 0, false);
>  
>  	hdrlen = sizeof(struct guehdr) + optlen;
> +	if (skb_cow_head(skb, hdrlen + sizeof(struct udphdr)))
> +		return -ENOMEM;

My understanding is this takes into account the UDP header pushed in
fou_build_udp. Isn't fou_build_header also affected by the same issue
then? (If so check the IPv6 paths too).

Also please check Sashiko's output,
https://sashiko.dev/#/patchset/20260801060115.3538849-1-nicoyip.dev%40gmail.com
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.