linux/include
Christian Brauner 28aaa9c399
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 rb_node with an 8-byte rhash_head
in struct pid, shrinking it from 160 to 144 bytes.

struct kthread (without CONFIG_BLK_CGROUP) is also 144 bytes. With
CONFIG_SLAB_MERGE_DEFAULT and SLAB_HWCACHE_ALIGN both round up to
192 bytes and share the same slab cache. struct pid.rcu.func and
struct kthread.affinity_node both sit at offset 0x78.

When a kthread exits via make_task_dead() it bypasses kthread_exit() and
misses the affinity_node cleanup. free_kthread_struct() frees the memory
while the node is still linked into the global kthread_affinity_list. A
subsequent list_del() by another kthread writes through dangling list
pointers into the freed and reused memory, corrupting the pid's
rcu.func pointer.

Instead of patching free_kthread_struct() to handle the missed cleanup,
consolidate all kthread exit paths. Turn kthread_exit() into a macro
that calls do_exit() and add kthread_do_exit() which is called from
do_exit() for any task with PF_KTHREAD set. This guarantees that
kthread-specific cleanup always happens regardless of the exit path -
make_task_dead(), direct do_exit(), or kthread_exit().

Replace __to_kthread() with a new tsk_is_kthread() accessor in the
public header. Export do_exit() since module code using the
kthread_exit() macro now needs it directly.

Reported-by: Guillaume Tucker <gtucker@gtucker.io>
Tested-by: Guillaume Tucker <gtucker@gtucker.io>
Tested-by: Mark Brown <broonie@kernel.org>
Tested-by: David Gow <davidgow@google.com>
Cc: <stable@vger.kernel.org>
Link: https://lore.kernel.org/all/20260224-mittlerweile-besessen-2738831ae7f6@brauner
Co-developed-by: Linus Torvalds <torvalds@linux-foundation.org>
Fixes: 4d13f4304f ("kthread: Implement preferred affinity")
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-02-26 10:45:49 +01:00
..
acpi mailbox: platform and core updates 2026-02-14 11:13:32 -08:00
asm-generic hyperv-next for v7.0 2026-02-20 08:48:31 -08:00
clocksource
crypto Networking changes for 7.0 2026-02-11 19:31:52 -08:00
cxl
drm drm/pagemap: pass pagemap_addr by reference 2026-02-17 19:39:44 -05:00
dt-bindings phy-for-7.0 2026-02-17 11:40:04 -08:00
hyperv hyperv-next for v7.0 2026-02-20 08:48:31 -08:00
keys keys/trusted_keys: establish PKWM as a trusted source 2026-01-30 09:27:26 +05:30
kunit treewide: Replace kmalloc with kmalloc_obj for non-scalar types 2026-02-21 01:02:28 -08:00
kvm KVM: arm64: Use standard seq_file iterator for vgic-debug debugfs 2026-02-02 10:59:25 +00:00
linux kthread: consolidate kthread exit paths to prevent use-after-free 2026-02-26 10:45:49 +01:00
math-emu
media [GIT PULL for v7.0] media updates 2026-02-11 12:20:25 -08:00
memory
misc
net Convert more 'alloc_obj' cases to default GFP_KERNEL arguments 2026-02-21 20:03:00 -08:00
pcmcia
ras
rdma RDMA v7.0 merge window 2026-02-12 17:05:20 -08:00
rv rv: Fix multiple definition of __pcpu_unique_da_mon_this 2026-02-20 13:12:00 +01:00
scsi SCSI misc on 20260212 2026-02-12 15:43:02 -08:00
soc
sound ASoC: Updates for v7.0 2026-02-09 17:39:11 +01:00
target
trace vfs-7.0-rc1.misc.2 2026-02-16 13:00:36 -08:00
uapi drm next fixes for 7.0-rc1 2026-02-20 15:36:38 -08:00
ufs scsi: ufs: host: mediatek: Require CONFIG_PM 2026-02-03 22:28:44 -05:00
vdso
video
xen Partial revert "x86/xen: fix balloon target initialization for PVH dom0" 2026-02-02 07:31:22 +01:00
Kbuild