CVE-2026-74609

Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
22/08/2026
Last modified:
22/08/2026

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> tipc: read le-&gt;link under the node lock in tipc_node_link_down()<br /> <br /> tipc_node_link_down() caches the link pointer before taking n-&gt;lock:<br /> <br /> struct tipc_link *l = le-&gt;link; /* unlocked */<br /> <br /> if (!l)<br /> return;<br /> tipc_node_write_lock(n);<br /> if (!tipc_link_is_establishing(l)) { /* deref l */<br /> ...<br /> tipc_link_reset(l); /* write into l */<br /> if (delete) {<br /> kfree(l);<br /> le-&gt;link = NULL;<br /> <br /> The delete=true caller frees that very object under n-&gt;lock, so the lock<br /> does not protect the cached pointer against it:<br /> <br /> - CPU A, delete=false: tipc_rcv() on TIPC_LINK_DOWN_EVT, or the link<br /> supervision timer via tipc_node_timeout(), reads l unlocked and then<br /> dereferences it under n-&gt;lock;<br /> - CPU B, delete=true: netlink TIPC_NL_BEARER_DISABLE -&gt; bearer_disable()<br /> -&gt; tipc_node_delete_links() -&gt; tipc_node_link_down(n, bearer_id, true)<br /> -&gt; kfree(l).<br /> <br /> The link is freed with plain kfree(), not kfree_rcu(), and for UDP bearers<br /> disable_media() only schedules the asynchronous cleanup_bearer() work, so<br /> its synchronize_net() runs after the links are already gone. An in-flight<br /> CPU A that has read l therefore dereferences freed memory once B frees it:<br /> a use-after-free read in tipc_link_is_establishing(), and a use-after-free<br /> write via tipc_link_reset() on the establishing branch.<br /> <br /> The following trace was captured on 7.2.0-rc5-00284-gaf39eb111ce6:<br /> <br /> BUG: KASAN: slab-use-after-free in tipc_link_is_establishing (net/tipc/link.c:285)<br /> Read of size 4 at addr ffff88802e2aa068 by task swapper/2/0<br /> tipc_link_is_establishing (net/tipc/link.c:285)<br /> tipc_node_link_down (net/tipc/node.c:1076)<br /> tipc_node_timeout (net/tipc/node.c:843)<br /> Allocated by task 9549:<br /> tipc_link_create (net/tipc/link.c:490)<br /> tipc_node_check_dest (net/tipc/node.c:1279)<br /> tipc_disc_rcv (net/tipc/discover.c:252)<br /> tipc_udp_recv (net/tipc/udp_media.c:389)<br /> Freed by task 9549:<br /> tipc_node_link_down (net/tipc/node.c:1084)<br /> tipc_node_delete_links (net/tipc/node.c:1320)<br /> bearer_disable (net/tipc/bearer.c:414)<br /> __tipc_nl_bearer_disable (net/tipc/bearer.c:992)<br /> <br /> Move the le-&gt;link read inside tipc_node_write_lock(), so it is serialised<br /> against the kfree() in the delete path. A racing teardown now either has<br /> not run yet, and we see a valid link, or has already run, and we see NULL.

Impact