Re: [PATCH net v2] seg6: Fix unset mac header in SRv6 End.DT VRF decapsulation

From: yymh

Date: Sun Oct 18 2026 - 07:44:12 EST


Thanks, Willem.

Andrea, David Ahern, could you share your thoughts on the v2 approach?
In particular, does restoring the mac header after l3mdev_l3_rcv()
returns properly fix the issue without introducing any regressions,
especially in the VRF sniffer path?

Thanks,
Boyan


Willem de Bruijn <willemdebruijn.kernel@xxxxxxxxx> 于2026年10月17日周六 23:57写道:
>
> Boyan Liu wrote:
> > SRv6 End.DT4/End.DT6 VRF decapsulation unsets the mac header in
> > end_dt_vrf_rcv() so that the VRF device can rebuild it for packet
> > sniffers. The VRF rx handler only performs the rebuild when a
> > sniffer is actually attached to the VRF device (ptype_all
> > non-empty); otherwise the packet continues up the stack with
> > mac_header == 0xffff.
> >
> > Every other receive path delivers packets with a valid mac header:
> > NIC drivers set it in eth_type_trans(), and tunnels without an L2
> > header (ipip, sit, gre, tun) reset it to the network header after
> > decapsulation. skb_mac_header() even warns on the unset state with
> > DEBUG_NET_WARN_ON_ONCE().
> >
> > If the decapsulated packet is an unexpected UDP GSO packet,
> > udp_queue_rcv_skb() re-segments it after restoring skb->data to the
> > mac header with __skb_push(skb, -skb_mac_offset(skb)). With the mac
> > header unset, skb_mac_offset() returns a large positive value,
> > which the unsigned __skb_push() argument turns into a huge length:
> > skb->data moves far outside the buffer and skb->len is corrupted,
> > so segmentation reads out of bounds:
> >
> > BUG: KASAN: slab-out-of-bounds in inet_gso_segment (net/ipv4/af_inet.c:1383)
> > Read of size 1 at addr ffff88800da7ffff by task exploit/149
> > Call Trace:
> > inet_gso_segment (net/ipv4/af_inet.c:1383)
> > skb_mac_gso_segment (net/core/gso.c:53)
> > __skb_gso_segment (net/core/gso.c:124)
> > udp_queue_rcv_skb (net/ipv4/udp.c:2476 net/ipv4/udp.c:2466)
> > udp_unicast_rcv_skb (net/ipv4/udp.c:2620)
> > ip_local_deliver (net/ipv4/ip_input.c:262)
> > seg6_local_input_core (net/ipv6/seg6_local.c:1640)
> > lwtunnel_input (net/core/lwtunnel.c:465)
> > ipv6_rcv (net/ipv6/ip6_input.c:351)
> >
> > Restore a valid mac header, pointing at the network header, once
> > the VRF rx handler returns. The sniffer rebuild happens inside the
> > handler while the header is still unset, so tap behavior is
> > unchanged; when no rebuild happened, the packet now carries the
> > same mac header state as any packet received on an L3 device.
> >
> > Fixes: 664d6f86868b ("seg6: add support for the SRv6 End.DT4 behavior")
> > Cc: stable@xxxxxxxxxxxxxxx
> > Reported-by: co+98d7de09cd94fec5@xxxxxxx
> > Signed-off-by: Boyan Liu <yymhvert@xxxxxxxxx>
> > ---
> > v2:
> > - Move the fix from the UDP GSO path to seg6local.
> > - Restore the mac header after the VRF rx handler returns, preserving
> > the VRF sniffer behavior.
> > - Verify the original reproducer, datagram delivery, and VRF sniffer
> > output under QEMU.
> > v1: https://lore.kernel.org/netdev/20261010073015.7665-1-yymhvert@xxxxxxxxx/
>
> Thanks. As discussed in v1, this sounds the better approach to me too.
> But it would be better to get the opinion of experts on VRF and SRv6.