Re: [PATCH net] tipc: protect node reset trace dump with node lock

From: Chengfeng Ye

Date: Mon Aug 24 2026 - 08:08:24 EST


On Mon, Aug 24, 2026 at 4:36 PM Tung Quang Nguyen
<tung.quang.nguyen@xxxxxxxx> wrote:
>
> Please decode above stack trace (using linux/scripts/decode_stacktrace.sh).
>

Decoded with linux/scripts/decode_stacktrace.sh against
(7.2.0-05126-ga4ff2be345d0-dirty #26).

BUG: KASAN: slab-use-after-free in tipc_link_dump (net/tipc/link.c:2910)
Read of size 4 at addr ffff88811c935800 by task poc/115
Call Trace:
tipc_link_dump (net/tipc/link.c:2910)
tipc_node_dump (net/tipc/node.c:3136)
trace_event_raw_event_tipc_node_class (net/tipc/trace.h:327)
tipc_node_reset_links (net/tipc/trace.h:360 / net/tipc/node.c:1337)
tipc_rcv (net/tipc/node.c:1851 / net/tipc/node.c:2159)
tipc_udp_recv (net/tipc/udp_media.c:389)
Allocated by task 0:
tipc_link_create (net/tipc/link.c:490)
tipc_node_check_dest (net/tipc/node.c:1285)
tipc_disc_rcv (net/tipc/discover.c:252)
Freed by task 117:
kfree (mm/slub.c:6692)
tipc_node_link_down (net/tipc/node.c:1090)
tipc_node_delete_links (net/tipc/node.c:1326)
bearer_disable (net/tipc/bearer.c:414)

The KASAN is obtained by using the following kernel-side delay()
instrumentation to make the reproduction deterministic.

```
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 683a136e53ef..0e7cdbee9459 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -34,6 +34,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/

+#include <linux/delay.h>
#include "core.h"
#include "link.h"
#include "node.h"
@@ -3129,7 +3130,11 @@ int tipc_node_dump(struct tipc_node *n, bool
more, char *buf)
i += scnprintf(buf + i, sz - i, " media: ");
i += tipc_media_addr_printf(buf + i, sz - i, &n->links[0].maddr);
i += scnprintf(buf + i, sz - i, "\n");
- i += tipc_link_dump(n->links[0].link, TIPC_DUMP_NONE, buf + i);
+ {
+ struct tipc_link *l0 = n->links[0].link;
+ mdelay(50);
+ i += tipc_link_dump(l0, TIPC_DUMP_NONE, buf + i);
+ }
i += scnprintf(buf + i, sz - i, " inputq: ");
i += tipc_list_dump(&n->links[0].inputq, false, buf + i);

@@ -3138,7 +3143,11 @@ int tipc_node_dump(struct tipc_node *n, bool
more, char *buf)
i += scnprintf(buf + i, sz - i, " media: ");
i += tipc_media_addr_printf(buf + i, sz - i, &n->links[1].maddr);
i += scnprintf(buf + i, sz - i, "\n");
- i += tipc_link_dump(n->links[1].link, TIPC_DUMP_NONE, buf + i);
+ {
+ struct tipc_link *l1 = n->links[1].link;
+ mdelay(50);
+ i += tipc_link_dump(l1, TIPC_DUMP_NONE, buf + i);
+ }
i += scnprintf(buf + i, sz - i, " inputq: ");
i += tipc_list_dump(&n->links[1].inputq, false, buf + i);
```

>
> It is not correct using read lock because trace_tipc_node_reset_links() accesses link's queues that tipc_rcv() might access concurrently.
> Please test this:
>
> diff --git a/net/tipc/node.c b/net/tipc/node.c
> index 683a136e53ef..bd91378b7540 100644
> --- a/net/tipc/node.c
> +++ b/net/tipc/node.c
> @@ -1333,7 +1333,9 @@ static void tipc_node_reset_links(struct tipc_node *n)
>
> pr_warn("Resetting all links to %x\n", n->addr);
>
> + tipc_node_write_lock(n);
> trace_tipc_node_reset_links(n, true, " ");
> + tipc_node_write_unlock_fast(n);
> for (i = 0; i < MAX_BEARERS; i++) {
> tipc_node_link_down(n, i, false);
> }
>
> > for (i = 0; i < MAX_BEARERS; i++) {
> > tipc_node_link_down(n, i, false);
> > }
>
>

No problem, I will send a v2 to correct the fix.

Best regards,
Chengfeng