* [PATCH net v5 0/2] tipc: fix NULL deref in tipc_named_node_up() on empty publication list
@ 2026-07-17 18:30 Weiming Shi
2026-07-17 18:30 ` [PATCH net v5 1/2] " Weiming Shi
2026-07-17 18:30 ` [PATCH net v5 2/2] tipc: fix node reference leak when defer work is already pending Weiming Shi
0 siblings, 2 replies; 3+ messages in thread
From: Weiming Shi @ 2026-07-17 18:30 UTC (permalink / raw)
To: Jon Maloy, Tung Nguyen, netdev, tipc-discussion; +Cc: Xiang Mei, Weiming Shi
This series continues the fix for the NULL dereference in
tipc_named_node_up() on an empty publication list, on top of Tung
Nguyen's RFC that defers bulk distribution to a workqueue. Jon asked
us to test that approach. It fixes the reported bug in our two-node
QEMU setup (veth pair, UDP bearers, node-id addressing), both with an
unprivileged user namespace and as root.
These two patches fix two issues found during that testing.
Patch 1/2: tipc_net_finalize() does not check the return value of
tipc_nametbl_publish(). If the publish fails, for example on a
GFP_ATOMIC allocation failure, the node is finalized but cluster_scope
stays empty. The deferred worker then calls named_distribute() with an
empty list and hits the same NULL dereference, this time on the
workqueue. With this patch the worker re-checks the list and skips
cleanly, no crash and no link flap. The tail stamp in
named_distribute() also gets an empty-queue guard.
Patch 2/2: a repeated NODE_UP while the bulk work is pending takes a
node reference that is never dropped, because schedule_work() returns
false when the work is already queued. Found by flapping the bearer
during the defer window. One reference is leaked per repeated
NODE_UP.
Changes in v5:
- Replace the item-less bulk approach with Tung's defer-to-workqueue
approach, which Jon asked us to test and which fixes the reported
bug in our testing.
- Patch 1/2: handle tipc_nametbl_publish() failure in finalize, and
guard the tail stamp in named_distribute() against an empty list.
- Patch 2/2: fix the node reference leak when the defer work is
already pending.
Note: this series applies on top of Tung Nguyen's RFC "tipc: fix
NULL deref in tipc_named_node_up() on empty publication list".
Tested against eb3f4b7426cf plus the RFC.
Weiming Shi (2):
tipc: fix NULL deref in tipc_named_node_up() on empty publication list
tipc: fix node reference leak when defer work is already pending
net/tipc/name_distr.c | 11 +++++++++++
net/tipc/net.c | 3 ++-
net/tipc/node.c | 3 ++-
3 files changed, 15 insertions(+), 2 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH net v5 1/2] tipc: fix NULL deref in tipc_named_node_up() on empty publication list
2026-07-17 18:30 [PATCH net v5 0/2] tipc: fix NULL deref in tipc_named_node_up() on empty publication list Weiming Shi
@ 2026-07-17 18:30 ` Weiming Shi
2026-07-17 18:30 ` [PATCH net v5 2/2] tipc: fix node reference leak when defer work is already pending Weiming Shi
1 sibling, 0 replies; 3+ messages in thread
From: Weiming Shi @ 2026-07-17 18:30 UTC (permalink / raw)
To: Jon Maloy, Tung Nguyen, netdev, tipc-discussion
Cc: Xiang Mei, Weiming Shi, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Hoang Huu Le,
kernel test robot, linux-kernel
tipc_net_finalize() does not check the return value of
tipc_nametbl_publish(). If the publish fails, for example on a
GFP_ATOMIC allocation failure, the node state name never lands in
cluster_scope, but tn->finalized is still set. A worker deferred by
tipc_named_node_up() then wakes and calls named_distribute() with an
empty list and hits the same NULL dereference in
buf_msg(skb_peek_tail(list)) as the original bug, this time on the
tipc_node_dist_bulk workqueue. The reported crash:
KASAN: null-ptr-deref in range [0x00000000000000d8-0x00000000000000df]
RIP: 0010:tipc_named_node_up (net/tipc/name_distr.c:196)
tipc_named_node_up (net/tipc/name_distr.c:196 net/tipc/name_distr.c:221)
tipc_node_write_unlock (net/tipc/node.c:428)
tipc_rcv (net/tipc/node.c:2185)
tipc_udp_recv (net/tipc/udp_media.c:392)
Kernel panic - not syncing: Fatal exception in interrupt
Check the publish result and warn on failure, but still set finalized,
otherwise deferred workers would sleep forever. In
tipc_named_dist_cluster_scope() re-check cluster_scope after the wait
and skip the distribution when it is empty. This is a permanent
condition, so return 0 instead of an error, otherwise the link would
be bounced forever. Also guard the tail stamp in named_distribute()
itself, so a caller that misses the precondition gets a warning and a
link reset through the existing -ENOBUFS path instead of a crash.
Reproducing this needs an allocation failure during finalize, so I
verified it by stubbing out the publish call: both nodes log the
failure, the workers skip the distribution, no crash, no link flap.
The normal path is unchanged with the same two-node test.
Fixes: cad2929dc432 ("tipc: update a binding service via broadcast")
Reported-by: Xiang Mei <xmei5@asu.edu>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Tung Nguyen <tung.quang.nguyen@est.tech>
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
---
net/tipc/name_distr.c | 11 +++++++++++
net/tipc/net.c | 3 ++-
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index b764274df758..5b0fb09226fc 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -193,6 +193,10 @@ static int named_distribute(struct net *net, struct sk_buff_head *list,
skb_trim(skb, INT_H_SIZE + (msg_dsz - msg_rem));
__skb_queue_tail(list, skb);
}
+ if (skb_queue_empty(list)) {
+ pr_warn("Bulk publication list empty, nothing to distribute\n");
+ return 1;
+ }
hdr = buf_msg(skb_peek_tail(list));
msg_set_last_bulk(hdr);
msg_set_named_seqno(hdr, seqno);
@@ -253,6 +257,13 @@ int tipc_named_dist_cluster_scope(struct net *net, u32 dnode)
spin_unlock_bh(&tn->nametbl_lock);
read_lock_bh(&nt->cluster_scope_lock);
+ if (unlikely(list_empty(&nt->cluster_scope))) {
+ /* finalize is done but nothing was published (publish
+ * failed): a permanent state, nothing to synchronize.
+ */
+ read_unlock_bh(&nt->cluster_scope_lock);
+ return 0;
+ }
if (named_distribute(net, &head, dnode, &nt->cluster_scope, seqno)) {
read_unlock_bh(&nt->cluster_scope_lock);
return -ENOBUFS;
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 4c144e720ac1..2aa8812c551a 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -138,7 +138,8 @@ static void tipc_net_finalize(struct net *net, u32 addr)
tipc_named_reinit(net);
tipc_sk_reinit(net);
tipc_mon_reinit_self(net);
- tipc_nametbl_publish(net, &ua, &sk, addr);
+ if (!tipc_nametbl_publish(net, &ua, &sk, addr))
+ pr_warn("Failed to publish own node state\n");
atomic_inc(&tn->finalized);
wake_up_var(&tn->finalized);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH net v5 2/2] tipc: fix node reference leak when defer work is already pending
2026-07-17 18:30 [PATCH net v5 0/2] tipc: fix NULL deref in tipc_named_node_up() on empty publication list Weiming Shi
2026-07-17 18:30 ` [PATCH net v5 1/2] " Weiming Shi
@ 2026-07-17 18:30 ` Weiming Shi
1 sibling, 0 replies; 3+ messages in thread
From: Weiming Shi @ 2026-07-17 18:30 UTC (permalink / raw)
To: Jon Maloy, Tung Nguyen, netdev, tipc-discussion
Cc: Xiang Mei, Weiming Shi, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, linux-kernel
In tipc_node_write_unlock(), TIPC_NOTIFY_NODE_UP with an empty
cluster_scope takes a node reference and schedules n->work. If the
link flaps down and up while that work is still pending, the next
NODE_UP takes another reference, but schedule_work() returns false
and the extra reference is never dropped. The tipc_node structure
leaks.
Verified by flapping the bearer while the work is pending: one
reference is leaked per repeated NODE_UP, while the work is put only
once when it finally runs.
Drop the reference when the work was already queued.
Reported-by: Xiang Mei <xmei5@asu.edu>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
---
net/tipc/node.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/tipc/node.c b/net/tipc/node.c
index b545a47d6ccb..428c4eacd02f 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -447,7 +447,8 @@ static void tipc_node_write_unlock(struct tipc_node *n)
/* Defer bulk distribution to work queue */
if (rc > 0) {
tipc_node_get(n);
- schedule_work(&n->work);
+ if (!schedule_work(&n->work))
+ tipc_node_put(n);
} else if (rc < 0) {
/* Bring the link down to start over bulk distribution
* when the link is up again.
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-07-17 18:31 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-17 18:30 [PATCH net v5 0/2] tipc: fix NULL deref in tipc_named_node_up() on empty publication list Weiming Shi
2026-07-17 18:30 ` [PATCH net v5 1/2] " Weiming Shi
2026-07-17 18:30 ` [PATCH net v5 2/2] tipc: fix node reference leak when defer work is already pending Weiming Shi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox