[BUG] posix-cpu-timers: use-after-free in exec failure path

From: kidz0

Date: Sun Aug 02 2026 - 12:26:28 EST


Hi,

While auditing the posix-cpu-timers code, I found a use-after-free in
the exec failure path.

I was reviewing e362359ace6f ("posix-cpu-timers: Cleanup CPU timers
before freeing them during exec") and the fix for CVE-2022-2585. My
understanding is that e362359ace6f strengthens CPU timer cleanup in the
successful exec path, but there still appears to be a lifetime gap in a
fatal/failure path after non-leader exec/de_thread.

Kernel version: 6.12.100
Architecture: x86_64
Runtime: QEMU/KVM, 2 vCPUs, 4GB RAM
Config: CONFIG_SMP=y, CONFIG_KASAN=y, CONFIG_KASAN_GENERIC=y,
CONFIG_KASAN_INLINE=y, CONFIG_POSIX_TIMERS=y,
CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y, CONFIG_SLUB_DEBUG=y

The same run first hits the WARN_ON_ONCE() in timer_lock_sighand(),
indicating that the CPU timer is still queued during exit_itimers(),
and later reports the KASAN use-after-free from posix_cpu_timers_exit()
during release_task().

KASAN report excerpt:
------------[ cut here ]------------
WARNING: CPU: 0 PID: 176 at kernel/time/posix-cpu-timers.c:565
timer_lock_sighand+0xe3/0x130
Modules linked in:
CPU: 0 UID: 1000 PID: 176 Comm: repro Not tainted 6.12.100 #1
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
1.16.3-debian-1.16.3-2 04/01/2014
RIP: 0010:timer_lock_sighand+0xe3/0x130
Code: 83 bd 98 00 00 00 00 75 21 48 b8 00 00 00 00 00 fc ff df 4c 8d
65 78 4c 89 e2 48 c1 ea 03 80 3c 02 00 75 3b
RSP: 0018:ffff8881119ffa40 EFLAGS: 00010086
RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffffffb0ae6f7f
RDX: 1ffff11021d7c8db RSI: 0000000000000000 RDI: ffff88810ebe46d8
RBP: ffff88810ebe4640 R08: 0000000000000001 R09: ffffed102233ff57
R10: 0000000000000003 R11: ffffffffb471cfd2 R12: 0000000000000000
R13: ffffed1021d7c8dc R14: ffff8881119ffaa0 R15: ffff88810ebe46e0
FS: 0000000000000000(0000) GS:ffff88811aa00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000796ce0affff0 CR3: 0000000118966000 CR4: 0000000000750ef0
PKRU: 55555554
Call Trace:
<TASK>
posix_cpu_timer_del+0x7c/0x470
? __pfx_posix_cpu_timer_del+0x10/0x10
? __pfx__raw_spin_lock_irqsave+0x10/0x10
? __pfx__raw_spin_lock_irq+0x10/0x10
? __pfx__raw_spin_lock+0x10/0x10
exit_itimers+0x26f/0x4c0
? __pfx_exit_itimers+0x10/0x10
? _raw_spin_lock_irq+0x84/0xe0
? __pfx__raw_spin_lock_irq+0x10/0x10
do_exit+0x4ac/0x25e0
? __kasan_slab_free+0x37/0x50
? __pfx_do_exit+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? task_work_run+0x12d/0x200
? srso_alias_return_thunk+0x5/0xfbef5
? _raw_spin_lock_irq+0x84/0xe0
do_group_exit+0xb0/0x220
get_signal+0x1adb/0x1df0
? __pfx_get_signal+0x10/0x10
arch_do_signal_or_restart+0x8f/0x550
? __pfx_arch_do_signal_or_restart+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? srso_alias_return_thunk+0x5/0xfbef5
? do_execveat_common.isra.0+0x3ec/0x510
? getname_flags.part.0+0xae/0x480
syscall_exit_to_user_mode+0xa0/0xf0
do_syscall_64+0x64/0x120
entry_SYSCALL_64_after_hwframe+0x76/0x7e
RIP: 0033:0x401423
Code: 41 b8 3b 00 00 00 49 8b 51 10 48 89 44 24 48 48 89 de 4c 89 c0
48 89 7c 24 30 48 c7 44 24 38 7d 20 40 00 4f
RSP: 002b:0000796ce0afff60 EFLAGS: 00000246 ORIG_RAX: 000000000000003b
RAX: fffffffffffffffc RBX: 0000796ce0afff90 RCX: 0000000000401423
RDX: 00007ffc43c36078 RSI: 0000796ce0afff90 RDI: 00007ffc43c37fc8
RBP: 0000796ce0afff70 R08: 000000000000003b R09: 0000000000403160
R10: 0000000000000001 R11: 0000000000000246 R12: 00000000000000b1
R13: 00007ffc43c35fe8 R14: 0000000000000101 R15: 00007ffc43c35fb0
</TASK>
---[ end trace 0000000000000000 ]---
==================================================================
BUG: KASAN: slab-use-after-free in timerqueue_del+0xfc/0x120
Read of size 8 at addr ffff88810ebe46b8 by task repro/175

CPU: 1 UID: 1000 PID: 175 Comm: repro Tainted: G W 6.12.100 #1
Tainted: [W]=WARN
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
1.16.3-debian-1.16.3-2 04/01/2014
Call Trace:
<TASK>
dump_stack_lvl+0x5d/0x80
? timerqueue_del+0xfc/0x120
print_report+0x156/0x4d7
? __pfx__raw_spin_lock_irqsave+0x10/0x10
? timerqueue_del+0xfc/0x120
kasan_report+0xc6/0x100
? timerqueue_del+0xfc/0x120
timerqueue_del+0xfc/0x120
posix_cpu_timers_exit+0x17c/0x220
release_task+0x24b/0x1410
? srso_alias_return_thunk+0x5/0xfbef5
? thread_group_cputime_adjusted+0xca/0x120
? srso_alias_return_thunk+0x5/0xfbef5
? _raw_spin_lock_irq+0x84/0xe0
? __pfx_release_task+0x10/0x10
wait_consider_task+0x11d0/0x3c50
? __pfx_wait_consider_task+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? srso_alias_return_thunk+0x5/0xfbef5
? try_to_wake_up+0x7e3/0x1410
? srso_alias_return_thunk+0x5/0xfbef5
__do_wait+0x629/0x770
? __pfx_aa_may_signal+0x10/0x10
? __pfx___do_wait+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? add_wait_queue+0x100/0x230
? signal_wake_up_state+0x2b/0x40
do_wait+0x155/0x340
kernel_wait4+0x104/0x1d0
? __pfx_kernel_wait4+0x10/0x10
? __pfx_child_wait_callback+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? srso_alias_return_thunk+0x5/0xfbef5
? do_send_sig_info+0xcb/0x150
__do_sys_wait4+0x10b/0x120
? __pfx___do_sys_wait4+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? kill_something_info+0x23d/0x2b0
? srso_alias_return_thunk+0x5/0xfbef5
? switch_fpu_return+0xef/0x1e0
do_syscall_64+0x58/0x120
entry_SYSCALL_64_after_hwframe+0x76/0x7e
RIP: 0033:0x401aa2
Code: 60 85 ff 7e 0c b8 3e 00 00 00 be 09 00 00 00 0f 05 48 8b 7c 24
08 48 8d 74 24 1c 45 31 d2 b8 3d 00 00 00 b8
RSP: 002b:00007ffc43c35f90 EFLAGS: 00000246 ORIG_RAX: 000000000000003d
RAX: ffffffffffffffda RBX: 00007ffc43c35fab RCX: 0000000000401aa2
RDX: 0000000040000000 RSI: 00007ffc43c35fac RDI: 00000000000000b0
RBP: 00007ffc43c35fb8 R08: 0000000000000000 R09: 0000000000000144
R10: 0000000000000000 R11: 0000000000000246 R12: 00007ffc43c35fd8
R13: 00007ffc43c35fd0 R14: 00007ffc43c35fc8 R15: 00007ffc43c35fb0
</TASK>

The freed object belongs to posix_timers_cache, and the stale access is
through the embedded CPU timerqueue node in struct k_itimer.

LLM assistance was used during the auditing process that led to
identifying this bug. Following Documentation/process/security-bugs.rst,
I am treating this as public and am not including the full reproducer
source in this public message. I can provide the reproducer source
to the relevant maintainers on request.

Reported-by: Kijo Park <red993688@xxxxxxxxx>