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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox