Kernel race after non-leader exec frees POSIX timer on signal list
Lockless pending-signal cleanup can race with timer delivery when execve swaps thread IDs, leaving a use-after-free path.
A race in Linux signal handling can leave a freed POSIX timer still linked on a live task's pending list after a non-leader execve, culminating in a slab use-after-free on later signal delivery.
Hyunwoo Kim showed that an earlier change which flushes a dying task's pending queue without the signal lock rested on a false assumption for the old group leader. That work assumed that once the leader had passed exit teardown, no POSIX timer could still resolve to it. In a non-leader exec, thread-ID exchange runs before the leader is released, so a SIGEV_THREAD_ID timer created against the leader's tid now resolves to the thread that called exec. The timer and the lockless flush can then touch the same preallocated sigqueue at once.
If the timer signal is blocked, its queue entry stays on the leader's pending list. On the next expiry the delivery path can see the entry as unqueued in the middle of a non-atomic list delete, requeue it on the surviving thread, and have the flush's trailing store corrupt the new links. A later tgkill walks that pointer into memory already freed by RCU. Kim reproduced the failure under KASAN.
Kim's first fix ordered the list teardown so a plain emptiness check could not succeed until the flush had finished writing. Thomas Gleixner objected that this "cures the symptom and not the underlying problem" and, with Oleg Nesterov, pushed to clear the former leader's pending signals under the signal lock during de_thread before the lockless release path runs. Follow-up notes still weighed exactly when that flush must run relative to the tid handoff so a concurrent timer on another CPU cannot requeue onto the old leader afterward.