* [PATCH net v3 0/2] tipc: fix NULL deref in tipc_named_node_up() on empty publication list
@ 2026-07-14 17:41 Weiming Shi
2026-07-14 17:41 ` [PATCH net v3 1/2] tipc: guard against empty list in tipc_node_xmit() Weiming Shi
2026-07-14 17:41 ` [PATCH net v3 2/2] tipc: fix NULL deref in tipc_named_node_up() on empty publication list Weiming Shi
0 siblings, 2 replies; 5+ messages in thread
From: Weiming Shi @ 2026-07-14 17:41 UTC (permalink / raw)
To: Jon Maloy, netdev, tipc-discussion
Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Hoang Huu Le, Xiang Mei, Tung Quang Nguyen,
linux-kernel, Weiming Shi
named_distribute() stamps the last_bulk flag on the tail skb of the
publication list. When the list is empty no skb is enqueued and the tail
access dereferences NULL. tipc_named_node_up() hits this on an empty
cluster_scope, which happens with a node-id configuration where
cluster_scope is populated only later by tipc_net_finalize(). It is
reachable by an unprivileged user over a UDP bearer in a user+net
namespace.
Patch 1 guards tipc_node_xmit() against an empty list, so the allocation-
failure path in named_distribute() cannot pass an empty list down to
tipc_lxc_xmit(), which has the same tail-of-empty-list deref.
Patch 2 emits an item-less bulk when the publication list is empty, so the
peer still receives the last_bulk flag and does not stall this node's later
name updates.
Changes in v3:
- Split into two patches; add patch 1 to guard tipc_node_xmit() against
the tipc_lxc_xmit() deref reachable via the allocation-failure path.
- Break out of the build loop on allocation failure instead of returning,
so the last_bulk flag is still applied to the last queued skb.
Changes in v2:
- Instead of returning early on an empty cluster_scope (which would stall
the peer, since it waits for a bulk with the last_bulk flag before
accepting later name updates), emit an item-less bulk so the peer opens
normally.
Thanks to Tung Quang Nguyen for the review of v1.
Weiming Shi (2):
tipc: guard against empty list in tipc_node_xmit()
tipc: fix NULL deref in tipc_named_node_up() on empty publication list
net/tipc/name_distr.c | 16 +++++++++++++++-
net/tipc/node.c | 3 +++
2 files changed, 18 insertions(+), 1 deletion(-)
base-commit: 4595d2c77ea4bfe4ae0efa38770a59ee5d2f06d3
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH net v3 1/2] tipc: guard against empty list in tipc_node_xmit()
2026-07-14 17:41 [PATCH net v3 0/2] tipc: fix NULL deref in tipc_named_node_up() on empty publication list Weiming Shi
@ 2026-07-14 17:41 ` Weiming Shi
2026-07-14 17:41 ` [PATCH net v3 2/2] tipc: fix NULL deref in tipc_named_node_up() on empty publication list Weiming Shi
1 sibling, 0 replies; 5+ messages in thread
From: Weiming Shi @ 2026-07-14 17:41 UTC (permalink / raw)
To: Jon Maloy, netdev, tipc-discussion
Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Hoang Huu Le, Xiang Mei, Tung Quang Nguyen,
linux-kernel, Weiming Shi
tipc_node_xmit() passes @list to tipc_lxc_xmit(), which dereferences
buf_msg(skb_peek(list)) without checking, so an empty list causes a NULL
pointer dereference. named_distribute() can hand it an empty list when a
bulk allocation fails. tipc_link_xmit() was already guarded in commit
b77413446408 ("tipc: fix NULL deref in tipc_link_xmit()"); guard
tipc_node_xmit() itself so the tipc_lxc_xmit() path is covered too.
Fixes: f73b12812a3d ("tipc: improve throughput between nodes in netns")
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, 3 insertions(+)
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 97aa970a0d83..fc241e7b0c1f 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -1695,6 +1695,9 @@ int tipc_node_xmit(struct net *net, struct sk_buff_head *list,
int bearer_id;
int rc;
+ if (skb_queue_empty(list))
+ return 0;
+
if (in_own_node(net, dnode)) {
tipc_loopback_trace(net, list);
spin_lock_init(&list->lock);
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH net v3 2/2] tipc: fix NULL deref in tipc_named_node_up() on empty publication list
2026-07-14 17:41 [PATCH net v3 0/2] tipc: fix NULL deref in tipc_named_node_up() on empty publication list Weiming Shi
2026-07-14 17:41 ` [PATCH net v3 1/2] tipc: guard against empty list in tipc_node_xmit() Weiming Shi
@ 2026-07-14 17:41 ` Weiming Shi
2026-07-16 9:28 ` Tung Quang Nguyen
1 sibling, 1 reply; 5+ messages in thread
From: Weiming Shi @ 2026-07-14 17:41 UTC (permalink / raw)
To: Jon Maloy, netdev, tipc-discussion
Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Hoang Huu Le, Xiang Mei, Tung Quang Nguyen,
linux-kernel, Weiming Shi
named_distribute() ends by stamping the last_bulk flag on the tail skb via
buf_msg(skb_peek_tail(list)). When the publication list is empty no skb is
enqueued, skb_peek_tail() returns NULL, and buf_msg(NULL) is dereferenced.
tipc_named_node_up() runs this on &nt->cluster_scope. With a node-id
configuration cluster_scope is populated only later by tipc_net_finalize(),
so a peer link that comes up first reaches named_distribute() with an empty
list. It is reachable by an unprivileged user (TIPC genl ops use
GENL_UNS_ADMIN_PERM) over a UDP bearer in a user+net namespace:
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
The peer holds back this node's later name updates until it sees a bulk
with the last_bulk flag, so simply skipping the empty bulk would stall it.
Emit an item-less bulk when the list is empty, and break out of the build
loop on allocation failure instead of returning, so the last_bulk flag is
applied to the last queued skb.
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: Weiming Shi <bestswngs@gmail.com>
---
net/tipc/name_distr.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index ba4f4906e13b..dbcfa965de34 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -165,7 +165,7 @@ static void named_distribute(struct net *net, struct sk_buff_head *list,
dnode);
if (!skb) {
pr_warn("Bulk publication failure\n");
- return;
+ break;
}
hdr = buf_msg(skb);
msg_set_bc_ack_invalid(hdr, true);
@@ -192,6 +192,20 @@ static void 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)) {
+ skb = named_prepare_buf(net, PUBLICATION, 0, dnode);
+ if (!skb) {
+ pr_warn("Bulk publication failure\n");
+ return;
+ }
+ hdr = buf_msg(skb);
+ msg_set_bc_ack_invalid(hdr, true);
+ msg_set_bulk(hdr);
+ msg_set_non_legacy(hdr);
+ __skb_queue_tail(list, skb);
+ }
+
hdr = buf_msg(skb_peek_tail(list));
msg_set_last_bulk(hdr);
msg_set_named_seqno(hdr, seqno);
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* RE: [PATCH net v3 2/2] tipc: fix NULL deref in tipc_named_node_up() on empty publication list
2026-07-14 17:41 ` [PATCH net v3 2/2] tipc: fix NULL deref in tipc_named_node_up() on empty publication list Weiming Shi
@ 2026-07-16 9:28 ` Tung Quang Nguyen
2026-07-16 19:06 ` Weiming Shi
0 siblings, 1 reply; 5+ messages in thread
From: Tung Quang Nguyen @ 2026-07-16 9:28 UTC (permalink / raw)
To: Weiming Shi
Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Xiang Mei, linux-kernel, Jon Maloy, netdev,
tipc-discussion
>named_distribute() ends by stamping the last_bulk flag on the tail skb via
>buf_msg(skb_peek_tail(list)). When the publication list is empty no skb is
>enqueued, skb_peek_tail() returns NULL, and buf_msg(NULL) is dereferenced.
>
>tipc_named_node_up() runs this on &nt->cluster_scope. With a node-id
>configuration cluster_scope is populated only later by tipc_net_finalize(), so a
>peer link that comes up first reaches named_distribute() with an empty list. It
>is reachable by an unprivileged user (TIPC genl ops use
>GENL_UNS_ADMIN_PERM) over a UDP bearer in a user+net namespace:
>
> 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
>
>The peer holds back this node's later name updates until it sees a bulk with the
>last_bulk flag, so simply skipping the empty bulk would stall it.
>Emit an item-less bulk when the list is empty, and break out of the build loop
>on allocation failure instead of returning, so the last_bulk flag is applied to the
>last queued skb.
>
>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: Weiming Shi <bestswngs@gmail.com>
>---
> net/tipc/name_distr.c | 16 +++++++++++++++-
> 1 file changed, 15 insertions(+), 1 deletion(-)
>
>diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index
>ba4f4906e13b..dbcfa965de34 100644
>--- a/net/tipc/name_distr.c
>+++ b/net/tipc/name_distr.c
>@@ -165,7 +165,7 @@ static void named_distribute(struct net *net, struct
>sk_buff_head *list,
> dnode);
> if (!skb) {
> pr_warn("Bulk publication failure\n");
>- return;
>+ break;
> }
> hdr = buf_msg(skb);
> msg_set_bc_ack_invalid(hdr, true);
>@@ -192,6 +192,20 @@ static void 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)) {
>+ skb = named_prepare_buf(net, PUBLICATION, 0, dnode);
>+ if (!skb) {
>+ pr_warn("Bulk publication failure\n");
>+ return;
>+ }
This approach is wrong because:
1. When 'list' is empty, it is caused by memory allocation failure before. So, it is likely that 'skb' could be NULL again because of memory allocation failure.
2. Even if 'skb' is not NULL, allocation of non-data (zero-in-size) message will break the receiving peer when it handles this message.
>+ hdr = buf_msg(skb);
>+ msg_set_bc_ack_invalid(hdr, true);
>+ msg_set_bulk(hdr);
>+ msg_set_non_legacy(hdr);
>+ __skb_queue_tail(list, skb);
>+ }
>+
> hdr = buf_msg(skb_peek_tail(list));
> msg_set_last_bulk(hdr);
> msg_set_named_seqno(hdr, seqno);
>--
>2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net v3 2/2] tipc: fix NULL deref in tipc_named_node_up() on empty publication list
2026-07-16 9:28 ` Tung Quang Nguyen
@ 2026-07-16 19:06 ` Weiming Shi
0 siblings, 0 replies; 5+ messages in thread
From: Weiming Shi @ 2026-07-16 19:06 UTC (permalink / raw)
To: Tung Quang Nguyen
Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Xiang Mei, linux-kernel, Jon Maloy, netdev,
tipc-discussion
Tung Quang Nguyen <tung.quang.nguyen@est.tech> 于2026年7月16日周四 17:28写道:
>
> >named_distribute() ends by stamping the last_bulk flag on the tail skb via
> >buf_msg(skb_peek_tail(list)). When the publication list is empty no skb is
> >enqueued, skb_peek_tail() returns NULL, and buf_msg(NULL) is dereferenced.
> >
> >tipc_named_node_up() runs this on &nt->cluster_scope. With a node-id
> >configuration cluster_scope is populated only later by tipc_net_finalize(), so a
> >peer link that comes up first reaches named_distribute() with an empty list. It
> >is reachable by an unprivileged user (TIPC genl ops use
> >GENL_UNS_ADMIN_PERM) over a UDP bearer in a user+net namespace:
> >
> > 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
> >
> >The peer holds back this node's later name updates until it sees a bulk with the
> >last_bulk flag, so simply skipping the empty bulk would stall it.
> >Emit an item-less bulk when the list is empty, and break out of the build loop
> >on allocation failure instead of returning, so the last_bulk flag is applied to the
> >last queued skb.
> >
> >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: Weiming Shi <bestswngs@gmail.com>
> >---
> > net/tipc/name_distr.c | 16 +++++++++++++++-
> > 1 file changed, 15 insertions(+), 1 deletion(-)
> >
> >diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index
> >ba4f4906e13b..dbcfa965de34 100644
> >--- a/net/tipc/name_distr.c
> >+++ b/net/tipc/name_distr.c
> >@@ -165,7 +165,7 @@ static void named_distribute(struct net *net, struct
> >sk_buff_head *list,
> > dnode);
> > if (!skb) {
> > pr_warn("Bulk publication failure\n");
> >- return;
> >+ break;
> > }
> > hdr = buf_msg(skb);
> > msg_set_bc_ack_invalid(hdr, true);
> >@@ -192,6 +192,20 @@ static void 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)) {
> >+ skb = named_prepare_buf(net, PUBLICATION, 0, dnode);
> >+ if (!skb) {
> >+ pr_warn("Bulk publication failure\n");
> >+ return;
> >+ }
>
> This approach is wrong because:
> 1. When 'list' is empty, it is caused by memory allocation failure before. So, it is likely that 'skb' could be NULL again because of memory allocation failure.
> 2. Even if 'skb' is not NULL, allocation of non-data (zero-in-size) message will break the receiving peer when it handles this message.
>
> >+ hdr = buf_msg(skb);
> >+ msg_set_bc_ack_invalid(hdr, true);
> >+ msg_set_bulk(hdr);
> >+ msg_set_non_legacy(hdr);
> >+ __skb_queue_tail(list, skb);
> >+ }
> >+
> > hdr = buf_msg(skb_peek_tail(list));
> > msg_set_last_bulk(hdr);
> > msg_set_named_seqno(hdr, seqno);
> >--
> >2.43.0
>
Thanks for your review. Fixed and v4 sent.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-07-16 19:07 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-14 17:41 [PATCH net v3 0/2] tipc: fix NULL deref in tipc_named_node_up() on empty publication list Weiming Shi
2026-07-14 17:41 ` [PATCH net v3 1/2] tipc: guard against empty list in tipc_node_xmit() Weiming Shi
2026-07-14 17:41 ` [PATCH net v3 2/2] tipc: fix NULL deref in tipc_named_node_up() on empty publication list Weiming Shi
2026-07-16 9:28 ` Tung Quang Nguyen
2026-07-16 19:06 ` Weiming Shi
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®