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
next prev parent 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®