Re: [PATCH V2] signal: Prevent exec() race

From: Thomas Gleixner

Date: Thu Sep 03 2026 - 02:45:58 EST


On Wed, Sep 02 2026 at 16:19, Oleg Nesterov wrote:
> This is subjective and mostly cosmetic, but what do you think
> about the alternative change below?
>
> I won't insist, but to me both the patch and resulting code look
> a bit simpler this way.

Yeah, though if we restructure the code then I rather prefer to get rid
of the gotos and also move the cgroup...end() part out of the sighand
lock held region to make that as short as possible.

void exit_signals(struct task_struct *tsk)
{
LIST_HEAD(sigq_list);
int group_stop = 0;

/*
* @tsk is about to have PF_EXITING set - lock out users which
* expect a stable threadgroup.
*/
cgroup_threadgroup_change_begin(tsk);

scoped_guard(spinlock_irq, &tsk->sighand->siglock) {
tsk->flags |= PF_EXITING;

sigqueue_dequeue_pending(&tsk->pending, &sigq_list);

if (task_sigpending(tsk) && !thread_group_empty(tsk) &&
!(tsk->signal->flags & SIGNAL_GROUP_EXIT)) {
sigset_t unblocked = tsk->blocked;

signotset(&unblocked);
retarget_shared_pending(tsk, &unblocked);

if (unlikely(tsk->jobctl & JOBCTL_STOP_PENDING) &&
task_participate_group_stop(tsk))
group_stop = CLD_STOPPED;
}
}

cgroup_threadgroup_change_end(tsk);

flush_sigqueue_list(&sigq_list);

/*
* If group stop has completed, deliver the notification. This
* should always go to the real parent of the group leader.
*/
if (unlikely(group_stop)) {
read_lock(&tasklist_lock);
do_notify_parent_cldstop(tsk, false, group_stop);
read_unlock(&tasklist_lock);
}
}