Re: [PATCH net] tipc: protect node reset trace dump with node lock
Chengfeng Ye <[email protected]>
| Newsgroups | org.kernel.vger.stable,org.kernel.vger.linux-kernel,org.kernel.vger.netdev |
|---|---|
| Message-ID | <CAAo+4rVXE2gsdueg3Z1A1aWvmZthCgQWQjEfC4PbAmSDCBsoDA@mail.gmail.com> |
On Mon, Aug 24, 2026 at 4:36 PM Tung Quang Nguyen <[email protected]> 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