From: Chengfeng Ye <nicoyip.dev@gmail.com>
To: Jon Maloy <jmaloy@redhat.com>,
Tung Quang Nguyen <tung.quang.nguyen@est.tech>
Cc: "David S . Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Simon Horman <horms@kernel.org>,
netdev@vger.kernel.org, tipc-discussion@lists.sourceforge.net,
linux-kernel@vger.kernel.org,
Chengfeng Ye <nicoyip.dev@gmail.com>,
stable@vger.kernel.org
Subject: [PATCH net v2 2/2] tipc: serialize publication purging with name table updates
Date: Fri, 2 Oct 2026 02:29:24 +0800 [thread overview]
Message-ID: <20261001182924.3928331-3-nicoyip.dev@gmail.com> (raw)
In-Reply-To: <20261001182924.3928331-1-nicoyip.dev@gmail.com>
tipc_publ_notify() walks a failed node publication list after the node lock
has been released. Its safe iterator is not protected by nametbl_lock,
which is acquired only inside tipc_publ_purge().
A concurrent withdrawal can unlink and schedule the saved next publication
for freeing. The purge iterator then advances to that removed publication.
It may access freed memory after the RCU grace period, or repeatedly follow
the self-linked binding_node before then.
The decoded causal stack is:
tipc_nametbl_remove_publ net/tipc/name_table.c:543
tipc_publ_purge net/tipc/name_distr.c:244
tipc_publ_notify net/tipc/name_distr.c:261
tipc_node_write_unlock net/tipc/node.c:425
tipc_node_link_down net/tipc/node.c:1094
tipc_node_delete_links net/tipc/node.c:1325
bearer_disable net/tipc/bearer.c:414
__tipc_nl_bearer_disable net/tipc/bearer.c:992
tipc_nl_bearer_disable net/tipc/bearer.c:1002
Move the failed node publications to a private list under nametbl_lock.
Select, unlink and purge one publication during each lock acquisition, so
no publication pointer is retained across an unlocked interval. Concurrent
withdrawals can remove entries from the private list under the same lock.
Holding the lock for the whole purge would keep bottom halves disabled
while removing every publication. Releasing it after each entry avoids
an excessive lock hold for nodes with many publications.
node_lost_contact() purges queued name-table updates before scheduling the
node-down notification. An update already dequeued by tipc_named_rcv()
holds nametbl_lock until it updates the publication list, so it completes
before the snapshot and is included. A publication accepted after the
snapshot remains on the live node list for a later contact.
Fixes: 9db9fdd1983e ("tipc: avoid to asynchronously notify subscriptions")
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/netdev/20260927180806.1315902-1-nicoyip.dev@gmail.com/
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
---
net/tipc/name_distr.c | 27 ++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index acf96562608b..9a400a1fa4d7 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -230,20 +230,16 @@ void tipc_named_node_up(struct net *net, u32 dnode, u16 capabilities)
*
* Invoked for each publication issued by a newly failed node.
* Removes publication structure from name table & deletes it.
+ * The caller must hold nametbl_lock and unlink the node subscription.
*/
static void tipc_publ_purge(struct net *net, struct publication *p)
{
- struct tipc_net *tn = tipc_net(net);
struct publication *_p;
struct tipc_uaddr ua;
tipc_uaddr(&ua, TIPC_SERVICE_RANGE, p->scope, p->sr.type,
p->sr.lower, p->sr.upper);
- spin_lock_bh(&tn->nametbl_lock);
_p = tipc_nametbl_remove_publ(net, &ua, &p->sk, p->key);
- if (_p)
- list_del_init(&_p->binding_node);
- spin_unlock_bh(&tn->nametbl_lock);
if (_p)
kfree_rcu(_p, rcu);
}
@@ -254,10 +250,27 @@ void tipc_publ_notify(struct net *net, struct list_head *nsub_list,
struct name_table *nt = tipc_name_table(net);
struct tipc_net *tn = tipc_net(net);
- struct publication *publ, *tmp;
+ struct publication *publ;
+ LIST_HEAD(purge_list);
- list_for_each_entry_safe(publ, tmp, nsub_list, binding_node)
+ spin_lock_bh(&tn->nametbl_lock);
+ /* Preserve publications learned after this node-down snapshot. */
+ list_splice_init(nsub_list, &purge_list);
+ spin_unlock_bh(&tn->nametbl_lock);
+
+ for (;;) {
+ spin_lock_bh(&tn->nametbl_lock);
+ if (list_empty(&purge_list)) {
+ spin_unlock_bh(&tn->nametbl_lock);
+ break;
+ }
+ publ = list_first_entry(&purge_list, struct publication,
+ binding_node);
+ list_del_init(&publ->binding_node);
tipc_publ_purge(net, publ);
+ spin_unlock_bh(&tn->nametbl_lock);
+ }
+
spin_lock_bh(&tn->nametbl_lock);
if (!(capabilities & TIPC_NAMED_BCAST))
nt->rc_dests--;
--
2.43.0
next prev parent reply other threads:[~2026-10-01 18:29 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-27 18:08 [PATCH net] " Chengfeng Ye
2026-09-29 11:14 ` Tung Quang Nguyen
2026-10-01 18:36 ` Chengfeng Ye
2026-09-30 0:10 ` netdev-bot+sashiko
2026-10-01 18:29 ` [PATCH net v2 0/2] tipc: fix publication lifetime races Chengfeng Ye
2026-10-01 18:29 ` [PATCH net v2 1/2] tipc: unlink publications without a node lookup Chengfeng Ye
2026-10-01 18:29 ` Chengfeng Ye [this message]
2026-10-01 18:34 ` [PATCH net v2 0/2] tipc: fix publication lifetime races netdev-bot+sinfo
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=20261001182924.3928331-3-nicoyip.dev@gmail.com \
--to=nicoyip.dev@gmail.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=jmaloy@redhat.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=stable@vger.kernel.org \
--cc=tipc-discussion@lists.sourceforge.net \
--cc=tung.quang.nguyen@est.tech \
/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®