From: Yuyang Huang <sigefriedhyy@gmail.com>
To: Yuyang Huang <sigefriedhyy@gmail.com>
Cc: "David S. Miller" <davem@davemloft.net>,
Amit Cohen <amcohen@nvidia.com>, David Ahern <dsahern@kernel.org>,
Eric Dumazet <edumazet@google.com>,
Ido Schimmel <idosch@nvidia.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Simon Horman <horms@kernel.org>,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org
Subject: [PATCH net-next] ipv6: Serialize hardware flag notifications
Date: Sat, 15 Aug 2026 18:54:36 +0900 [thread overview]
Message-ID: <20260815095436.90534-1-sigefriedhyy@gmail.com> (raw)
fib6_info_hw_flags_set() first performs a lockless check of fib6_node.
It then allocates a notification skb with GFP_KERNEL, which can sleep. A
concurrent route deletion can remove the route, set fib6_node to NULL, and
emit RTM_DELROUTE while the allocation sleeps. When the thread wakes up,
it can emit RTM_NEWROUTE for the already deleted route.
This can cause userspace routing daemons to receive RTM_DELROUTE followed
by RTM_NEWROUTE and incorrectly believe that the deleted route still
exists in the kernel.
Allocate the skb before taking tb6_lock, then recheck fib6_node while
holding the lock. Keep the lock until RTM_NEWROUTE is published. If route
deletion wins the race, the recheck sees NULL and drops the notification.
Otherwise, deletion cannot remove the route until RTM_NEWROUTE has been
published, preserving notification order.
RTM_DELROUTE is sent by fib6_del_route() with tb6_lock held, so
publishing RTM_NEWROUTE under the same lock is sufficient to guarantee
ordering. rt6_fill_node() does not sleep in this path, and the
notification uses GFP_ATOMIC, matching inet6_rt_notify() which already
broadcasts under tb6_lock.
The race was found by Sashiko during code review.
Fixes: 907eea486888 ("net: ipv6: Emit notification when fib hardware flags are changed")
Signed-off-by: Yuyang Huang <sigefriedhyy@gmail.com>
---
net/ipv6/route.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 16dfac54a259..73db4f630dcc 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -6463,6 +6463,7 @@ void fib6_info_hw_flags_set(struct net *net, struct fib6_info *f6i,
bool offload, bool trap, bool offload_failed)
{
u8 fib_notify_on_flag_change;
+ struct fib6_table *table;
struct sk_buff *skb;
int err;
@@ -6491,22 +6492,33 @@ void fib6_info_hw_flags_set(struct net *net, struct fib6_info *f6i,
if (!fib_notify_on_flag_change)
return;
+ table = f6i->fib6_table;
skb = nlmsg_new(rt6_nlmsg_size(f6i), GFP_KERNEL);
if (!skb) {
err = -ENOBUFS;
goto errout;
}
+ spin_lock_bh(&table->tb6_lock);
+ if (!rcu_dereference_protected(f6i->fib6_node,
+ lockdep_is_held(&table->tb6_lock))) {
+ spin_unlock_bh(&table->tb6_lock);
+ kfree_skb(skb);
+ return;
+ }
+
err = rt6_fill_node(net, skb, f6i, NULL, NULL, NULL, 0, RTM_NEWROUTE, 0,
0, 0, RT_DEL_REASON_UNSPEC);
if (err < 0) {
/* -EMSGSIZE implies BUG in rt6_nlmsg_size() */
WARN_ON(err == -EMSGSIZE);
+ spin_unlock_bh(&table->tb6_lock);
kfree_skb(skb);
goto errout;
}
- rtnl_notify(skb, net, 0, RTNLGRP_IPV6_ROUTE, NULL, GFP_KERNEL);
+ rtnl_notify(skb, net, 0, RTNLGRP_IPV6_ROUTE, NULL, GFP_ATOMIC);
+ spin_unlock_bh(&table->tb6_lock);
return;
errout:
--
2.43.0
next reply other threads:[~2026-08-15 9:54 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-15 9:54 Yuyang Huang [this message]
2026-08-19 11:50 ` [PATCH net-next] ipv6: Serialize hardware flag notifications Ido Schimmel
2026-08-20 11:42 ` Yuyang Huang
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=20260815095436.90534-1-sigefriedhyy@gmail.com \
--to=sigefriedhyy@gmail.com \
--cc=amcohen@nvidia.com \
--cc=davem@davemloft.net \
--cc=dsahern@kernel.org \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=idosch@nvidia.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.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 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.