* [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®