mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Andrea Mayer <andrea.mayer@uniroma2.it>
To: Yuya Kusakabe <yuya.kusakabe@gmail.com>
Cc: "David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@kernel.org>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	Simon Horman <horms@kernel.org>,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	Andrea Mayer <andrea.mayer@uniroma2.it>
Subject: Re: [PATCH net-next v2 1/2] seg6: skip the route refcount in seg6local IPv6 lookups
Date: Wed, 14 Oct 2026 01:58:19 +0200	[thread overview]
Message-ID: <20261014015819.f26040ee1b2adb4a90798df8@uniroma2.it> (raw)
In-Reply-To: <20261010-seg6-lookup-noref-v2-1-51c09dd98197@gmail.com>

On Sat, 10 Oct 2026 19:10:39 +0900
Yuya Kusakabe <yuya.kusakabe@gmail.com> wrote:

Hi Yuya,

Thanks for v2. I re-ran the BPF_PROG_TEST_RUN case from v1 on 32-bit ARM
with the changes of v2, and I could not reproduce the use-after-free
anymore.

> ip6_route_input() attaches the input route to the skb without taking a
> reference, relying on the RCU read-side section of the receive path.
> The seg6local input actions run in that same section, either directly
> from the seg6local input handler or from a netfilter okfn, yet
> seg6_lookup_any_nexthop() takes and drops a route reference for every
> packet.

For a packet queued with NFQUEUE, the okfn runs later from nf_reinject(),
under the rcu_read_lock() of the nfnetlink verdict handler. Is "that same
section" accurate for that case?

> [snip]
>  	if (!tbl_id && !oif) {
> +		flags |= RT6_LOOKUP_F_DST_NOREF;
>  		dst = ip6_route_input_lookup(net, skb->dev, &fl6, skb, flags);
> [snip]
> +		flags |= RT6_LOOKUP_F_DST_NOREF;
>  		rt = ip6_pol_route(net, table, oif, &fl6, skb, flags);

With RT6_LOOKUP_F_DST_NOREF, ip6_pol_route() no longer calls
ip6_hold_safe(). If the route it finds is released on another CPU during
the lookup, the packet can be dropped without an ICMP error. Before the
series, when ip6_hold_safe() did not get the reference on the released
route, the packet went to the next policy rule, or to ip6_null_entry and
its ICMPv6 Destination Unreachable. As far as I can see, only packets that
race with the release are affected. It is still a change in behavior, and
it would be worth at least mentioning it in the commit message.

> [snip]
>  int seg6_lookup_nexthop(struct sk_buff *skb,
>  			struct in6_addr *nhaddr, u32 tbl_id)
>  {
> -	return seg6_lookup_any_nexthop(skb, nhaddr, tbl_id, false, 0);
> +	int err;
> +
> +	rcu_read_lock();
> +	err = seg6_lookup_nexthop_noref(skb, nhaddr, tbl_id);
> +	if (!skb_dst_force(skb)) {
> +		struct dst_entry *dst;
> +
> +		dst = &dev_net(skb->dev)->ipv6.ip6_blk_hole_entry->dst;
> +		dst_hold(dst);
> +		skb_dst_set(skb, dst);
> +		err = dst->error;
> +	}
> +	rcu_read_unlock();
> +
> +	return err;
>  }

The split works, and the contract is now in the names. One detail is how
seg6_lookup_nexthop() takes its reference: after the noref lookup, with
skb_dst_force(). Because of this, the BPF LWT helpers are affected by this
race too. Before the series, when ip6_hold_safe() did not get the reference
on the released route, seg6_lookup_nexthop() returned 0 if a later policy
rule had a route, or -ENETUNREACH. Now it can return -EINVAL in both cases.
The Sashiko review points out the second one.

It would be good to keep seg6_lookup_nexthop() unchanged for the BPF
helpers, also while a route is being released. One idea, as a refinement of
the split, could be a common lookup function with a noref argument. For
example, seg6_lookup_any_nexthop_noref() would call it with noref set, and
seg6_lookup_nexthop() with noref clear, keeping the refcounted lookup it
had before the series. What do you think?

> [snip]

Ciao,
Andrea

  reply	other threads:[~2026-10-13 23:58 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-10 10:10 [PATCH net-next v2 0/2] seg6: skip route refcounts in seg6local lookups Yuya Kusakabe
2026-10-10 10:10 ` [PATCH net-next v2 1/2] seg6: skip the route refcount in seg6local IPv6 lookups Yuya Kusakabe
2026-10-13 23:58   ` Andrea Mayer [this message]
2026-10-15 14:31     ` Yuya Kusakabe
2026-10-15 14:30   ` Gabriel Goller
2026-10-15 14:38     ` Yuya Kusakabe
2026-10-10 10:10 ` [PATCH net-next v2 2/2] seg6: skip the route refcount in seg6local IPv4 lookups Yuya Kusakabe

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=20261014015819.f26040ee1b2adb4a90798df8@uniroma2.it \
    --to=andrea.mayer@uniroma2.it \
    --cc=davem@davemloft.net \
    --cc=edumazet@kernel.org \
    --cc=horms@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=yuya.kusakabe@gmail.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®