CVE-2026-43402: kthread: consolidate kthread exit paths to prevent use-after-free
In the Linux kernel, the following vulnerability has been resolved:
kthread: consolidate kthread exit paths to prevent use-after-free
Guillaume reported crashes via corrupted RCU callback function pointers during KUnit testing. The crash was traced back to the pidfs rhashtable conversion which replaced the 24-byte rbnode with an 8-byte rhashhead in struct pid, shrinking it from 160 to 144 bytes.
struct kthread (without CONFIGBLKCGROUP) is also 144 bytes. With CONFIGSLABMERGEDEFAULT and SLABHWCACHEALIGN both round up to 192 bytes and share the same slab cache. struct pid.rcu.func and struct kthread.affinitynode both sit at offset 0x78.
When a kthread exits via maketaskdead() it bypasses kthreadexit() and misses the affinitynode cleanup. freekthreadstruct() frees the memory while the node is still linked into the global kthreadaffinitylist. A subsequent listdel() by another kthread writes through dangling list pointers into the freed and reused memory, corrupting the pid's rcu.func pointer.
Instead of patching freekthreadstruct() to handle the missed cleanup, consolidate all kthread exit paths. Turn kthreadexit() into a macro that calls doexit() and add kthreaddoexit() which is called from doexit() for any task with PFKTHREAD set. This guarantees that kthread-specific cleanup always happens regardless of the exit path - maketaskdead(), direct doexit(), or kthreadexit().
Replace tokthread() with a new tskiskthread() accessor in the public header. Export doexit() since module code using the kthreadexit() macro now needs it directly.
Affected Software
Event History
Frequently Asked Questions
What kernel configuration and runtime conditions are associated with the corruption?
The reported issue requires struct pid and struct kthread to share a slab cache, which occurs when CONFIG_SLAB_MERGE_DEFAULT and SLAB_HWCACHE_ALIGN cause both structures to round up to 192 bytes. The affected kthread must exit through make_task_dead(), bypassing the cleanup normally performed by kthread_exit().
What happens after the missed cleanup?
The kthread affinity node remains linked in the global kthread_affinity_list after its kthread structure is freed. A later list_del() can write through the dangling pointers into reused memory and corrupt a pid object's RCU callback function pointer.
Are there observable signs of this issue?
The issue was reported as crashes involving corrupted RCU callback function pointers during KUnit testing. The provided information does not identify a specific userspace trigger or a broader detection method.