CVE-2026-72404
In CVE-2026-72404, the UAF in TIPC bearer teardown isn't caused by developers forgetting synchronization — they were using RCU, kfree_rcu, and synchronize_net throughout the code. The bug is subtler: dst_cache_destroy() must execute AFTER synchronize_net(), not before it, because dst_cache_destroy() calls free_percpu() immediately with no RCU grace period. This ordering requirement isn't documented in any dst_cache API contract. Three independent synchronization domains intersect during bearer teardown: the bearer structure's RCU-protected list traversal, dst_cache's per-CPU immediate-free semantics, and UDP socket reference counting. Each domain's safety contract is internally consistent, but their interaction creates ordering constraints that only become visible when destroying all three simultaneously. The fix adds call_rcu_hurry() for rcast entries precisely because they sit at the intersection of an RCU-protected list and dst_cache references — two independent synchronization concerns that must be sequenced correctly. Check your code for any path that calls dst_cache_destroy() before synchronize_net() or equivalent RCU barrier. If you hold dst_cache references while removing items from RCU-protected structures, those removals must go through RCU callbacks (call_rcu or call_rcu_hurry), not synchronous destruction. The dst_cache API makes no explicit guarantee about deferred destruction — treat dst_cache_destroy() as a synchronization operation with its own ordering requirements, not as simple memory cleanup. This class of vulnerability has recurred when per-CPU immediate-free semantics collide with RCU-protected callers; the pattern suggests similar ordering bugs likely exist in other subsystems mixing these patterns.
Reviewed through automated stages and approved by a human before publication.