All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrea Mayer <andrea.mayer@uniroma2.it>
To: Zhiling Zou <zhilinz@nebusec.ai>
Cc: netdev@vger.kernel.org, davem@davemloft.net,
	Jakub Kicinski <kuba@kernel.org>,
	edumazet@google.com, pabeni@redhat.com,
	David Ahern <dsahern@kernel.org>,
	horms@kernel.org, david.lebrun@uclouvain.be, vega@nebusec.ai,
	stefano.salsano@uniroma2.it,
	Andrea Mayer <andrea.mayer@uniroma2.it>
Subject: Re: [PATCH net 1/1] seg6: reset IP6CB after IPv6 decapsulation
Date: Wed, 19 Aug 2026 00:36:44 +0200	[thread overview]
Message-ID: <20260819003644.2f1b7a9b60d0ed22d37aca11@uniroma2.it> (raw)
In-Reply-To: <cb0b571546147162dd63bd3a93952144734b1503.1786896221.git.zhilinz@nebusec.ai>

On Mon, 17 Aug 2026 00:09:29 +0800
Zhiling Zou <zhilinz@nebusec.ai> wrote:

Hi Zhiling,

thank you for the patch and the reproducer. I reported the same stale
IP6CB while reviewing an IPv4 fix for the same helper [1].

Some comments below.

> decap_and_validate() pulls the outer SRv6 headers and makes the
> inner packet the skb network header. The IPv6 control block still
> contains values collected while parsing the outer packet, including
> nhoff and extension-header flags.
>
> End.DX6 and End.DT6 then route the inner IPv6 packet directly to
> the IPv6 input path. If an outer extension header left a large
> nhoff, ip6_protocol_deliver_rcu() reads
> skb_network_header(skb)[nhoff] from the inner packet, which may be
> beyond the skb head.

A KASAN trace trimmed to the relevant calls from the cover letter
would help here, along with the reachability. The commit is what
lands in git log.

> Clear IP6CB after IPv6 decapsulation, restore the incoming interface,
> and initialize nhoff to the inner IPv6 base-header nexthdr field before
> delivering the packet.
>
> Fixes: d7a669dd2f8b ("ipv6: sr: add helper functions for seg6local")
> Cc: stable@vger.kernel.org
> Reported-by: Vega <vega@nebusec.ai>
> Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
> ---
>  net/ipv6/seg6_local.c | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c
> index 2b41e4c0dddd1..4df76fa85d6b4 100644
> --- a/net/ipv6/seg6_local.c
> +++ b/net/ipv6/seg6_local.c
> @@ -253,6 +253,11 @@ static bool decap_and_validate(struct sk_buff *skb, int proto)
>
>  	skb_reset_network_header(skb);
>  	skb_reset_transport_header(skb);
> +	if (proto == IPPROTO_IPV6) {
> +		memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
> +		IP6CB(skb)->iif = skb->skb_iif;
> +		IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr);
> +	}
>  	if (iptunnel_pull_offloads(skb))
>  		return false;

The index would need to come from IP6CB->iif, saving it before the memset.
ip6_rcv_core() sets that field before l3mdev runs, and vrf_ip6_rcv() then
replaces skb->skb_iif with the master without touching IP6CB->iif.

I measured it on net/main and on two variants of the fix, one taking the
index from skb->skb_iif and one from IP6CB->iif. The receiver is a UDP
socket bound to the VRF reading IPV6_PKTINFO, the datagram arrives on
ifindex 8, and the VRF device is 9:

                          no patch   skb->skb_iif   IP6CB->iif
  without decapsulation          8              8            8
  End.DT6 vrftable               8              9            8
  End.DT6 table                  8              9            8

The patch that fixes the IPv4 side uses IP6CB->iif for this reason [2].

IP6SKB_L3SLAVE would also need to be carried across. vrf_ip6_rcv() sets
that flag on the outer packet, and the memset drops it.

Something like this:

	bool l3slave = ipv6_l3mdev_skb(IP6CB(skb)->flags);
	int iif = IP6CB(skb)->iif;

	memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
	IP6CB(skb)->iif = iif;
	IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr);
	if (l3slave)
		IP6CB(skb)->flags |= IP6SKB_L3SLAVE;

The fix for the IPv4 side of this helper is now at its v4 [2]. Both touch
decap_and_validate(), so your block would go next to theirs as an else if.

Thanks,

Ciao,
Andrea

[1] https://lore.kernel.org/netdev/20260809221915.2ffc1ecd0f445fcb70270e31@uniroma2.it/
[2] https://lore.kernel.org/netdev/20260817085839.946321-1-david.lee@trailofbits.com/

      reply	other threads:[~2026-08-18 22:37 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-16 16:09 [PATCH net 0/1] seg6: reset IP6CB after IPv6 decapsulation Zhiling Zou
2026-08-16 16:09 ` [PATCH net 1/1] " Zhiling Zou
2026-08-18 22:36   ` Andrea Mayer [this message]

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=20260819003644.2f1b7a9b60d0ed22d37aca11@uniroma2.it \
    --to=andrea.mayer@uniroma2.it \
    --cc=davem@davemloft.net \
    --cc=david.lebrun@uclouvain.be \
    --cc=dsahern@kernel.org \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=kuba@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=stefano.salsano@uniroma2.it \
    --cc=vega@nebusec.ai \
    --cc=zhilinz@nebusec.ai \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.