CVE-2026-64563 is a state synchronization failure in the rhashtable walk implementation. The function rhashtable_walk_start_check() has two restart paths—one for when the table was freed during resize, another for when the table remains valid. Only the 'table still valid' path clears iter->p (the iterator's current position pointer). The 'table freed' path correctly resets slot and skip but leaves iter->p dangling. This asymmetry creates a window where a pointer deemed stale in one path becomes a dangling reference in the other.
The practical exposure: both affected callers (netlink_diag and TIPC) perform multi-fragment walks across walk_stop/walk_start boundaries. Netlink_diag is used for socket diagnostics—unprivileged users with appropriate permissions can trigger resize races and potentially cause dangling pointer dereferences. TIPC adds a cluster communication vector.
The fix is trivial: adding iter->p = NULL to the 'table freed' restart path. But the deeper issue is that this is the third or fourth time rhashtable walk restart logic has had similar invariant violations. The pattern is predictable: iterator state lives across multiple fields (iter->p, iter->slot, iter->skip) that must be reset together, and when multiple restart paths exist, they get updated piecemeal across different commits and bug fixes.
For defenders: audit any rhashtable callers that perform multi-fragment walks—stop, resume, expect state consistency. Beyond netlink_diag and TIPC, treat the exposure surface as potentially larger than enumerated. The 'table freed' restart path is harder to trigger (requires resize during iteration), meaning it has seen less testing and is more likely to have accumulated drift. If you maintain code using rhashtable walks, verify that any walk_stop/walk_start pair handles both resize and non-resume scenarios correctly.