From: Chengfeng Ye <nicoyip.dev@gmail.com>
To: Jon Maloy <jmaloy@redhat.com>,
Tung Quang Nguyen <tung.quang.nguyen@est.tech>,
"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>,
Ying Xue <ying.xue@windriver.com>,
GhantaKrishnamurthy MohanKrishna
<mohan.krishna.ghanta.krishnamurthy@ericsson.com>
Cc: 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] tipc: hold a reference to nodes found by link name
Date: Sun, 27 Sep 2026 14:40:36 +0800 [thread overview]
Message-ID: <20260927064036.3691962-1-nicoyip.dev@gmail.com> (raw)
tipc_node_find_by_name() returns a node after dropping its RCU read lock
without taking a reference. The LINK_SET, LINK_GET and LINK_RESET_STATS
handlers then lock and access the node, racing with timer-driven cleanup
of a down peer. Generic netlink serialization does not exclude the node
timer.
The following interleaving can leave a handler using a freed node:
CPU 0: find the node under RCU and release the node read lock
CPU 1: tipc_node_timeout() clears the links and unlinks the down node
CPU 1: drop the list and timer references, queuing tipc_node_free()
CPU 0: leave the RCU read-side critical section
CPU 1: complete the grace period and free the node
CPU 0: acquire the node lock through the stale pointer
LINK_SET also uses the node's media address after releasing the node
lock, when passing queued packets to tipc_bearer_xmit().
KASAN reported:
BUG: KASAN: slab-use-after-free in _raw_read_lock_bh+0x1d/0x40
Write of size 4 at addr ffff888112723808 by task poc/87
Call Trace:
_raw_read_lock_bh+0x1d/0x40
tipc_nl_node_set_link+0x30e/0x680
genl_family_rcv_msg_doit+0x1e0/0x2c0
genl_rcv_msg+0x419/0x6d0
netlink_rcv_skb+0x11f/0x350
Allocated by task 28:
tipc_node_create+0x9c1/0x1fa0
tipc_node_check_dest+0x121/0x11e0
tipc_disc_rcv+0xdbf/0x1430
Freed by task 87:
kfree+0x149/0x330
rcu_core+0x50a/0x1850
Last potentially related work creation:
__call_rcu_common.constprop.0+0x71/0xa10
tipc_node_timeout+0xb1b/0xe70
Acquire a reference to the selected node with kref_get_unless_zero()
before leaving RCU, returning NULL if the node has already been released.
Release that reference on every caller exit after the last node access,
including transmission in LINK_SET. Keep the existing link lookup order
and locking so concurrent link removal still takes the existing error
paths.
Fixes: 6a939f365bdb ("tipc: Auto removal of peer down node instance")
Cc: stable@vger.kernel.org
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
---
net/tipc/node.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/net/tipc/node.c b/net/tipc/node.c
index bd91378b7540..2726bee3bb40 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -2424,6 +2424,8 @@ static struct tipc_node *tipc_node_find_by_name(struct net *net,
if (found_node)
break;
}
+ if (found_node && !kref_get_unless_zero(&found_node->kref))
+ found_node = NULL;
rcu_read_unlock();
return found_node;
@@ -2507,6 +2509,7 @@ int tipc_nl_node_set_link(struct sk_buff *skb, struct genl_info *info)
tipc_node_read_unlock(node);
tipc_bearer_xmit(net, bearer_id, &xmitq, &node->links[bearer_id].maddr,
NULL);
+ tipc_node_put(node);
return res;
}
@@ -2558,12 +2561,14 @@ int tipc_nl_node_get_link(struct sk_buff *skb, struct genl_info *info)
link = node->links[bearer_id].link;
if (!link) {
tipc_node_read_unlock(node);
+ tipc_node_put(node);
err = -EINVAL;
goto err_free;
}
err = __tipc_nl_add_link(net, &msg, link, 0);
tipc_node_read_unlock(node);
+ tipc_node_put(node);
if (err)
goto err_free;
}
@@ -2634,11 +2639,13 @@ int tipc_nl_node_reset_link_stats(struct sk_buff *skb, struct genl_info *info)
if (!link) {
spin_unlock_bh(&le->lock);
tipc_node_read_unlock(node);
+ tipc_node_put(node);
return -EINVAL;
}
tipc_link_reset_stats(link);
spin_unlock_bh(&le->lock);
tipc_node_read_unlock(node);
+ tipc_node_put(node);
return 0;
}
--
2.43.0
next reply other threads:[~2026-09-27 6:40 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-27 6:40 Chengfeng Ye [this message]
2026-09-28 12:17 ` [PATCH net] tipc: hold a reference to nodes found by link name Tung Quang Nguyen
2026-09-28 16:19 ` Chengfeng Ye
2026-09-30 0:42 ` netdev-bot+sashiko
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=20260927064036.3691962-1-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=mohan.krishna.ghanta.krishnamurthy@ericsson.com \
--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 \
--cc=ying.xue@windriver.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.