Skip to content

Commit 63dffec

Browse files
Frederic WeisbeckerKAGA-KOKO
Frederic Weisbecker
authored andcommitted
posix-timers: Target group sigqueue to current task only if not exiting
A sigqueue belonging to a posix timer, which target is not a specific thread but a whole thread group, is preferrably targeted to the current task if it is part of that thread group. However nothing prevents a posix timer event from queueing such a sigqueue from a reaped yet running task. The interruptible code space between exit_notify() and the final call to schedule() is enough for posix_timer_fn() hrtimer to fire. If that happens while the current task is part of the thread group target, it is proposed to handle it but since its sighand pointer may have been cleared already, the sigqueue is dropped even if there are other tasks running within the group that could handle it. As a result posix timers with thread group wide target may miss signals when some of their threads are exiting. Fix this with verifying that the current task hasn't been through exit_notify() before proposing it as a preferred target so as to ensure that its sighand is still here and stable. complete_signal() might still reconsider the choice and find a better target within the group if current has passed retarget_shared_pending() already. Fixes: bcb7ee7 ("posix-timers: Prefer delivery of signals to the current thread") Reported-by: Anthony Mallet <[email protected]> Suggested-by: Oleg Nesterov <[email protected]> Signed-off-by: Frederic Weisbecker <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Acked-by: Oleg Nesterov <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/all/[email protected] Closes: https://lore.kernel.org/all/[email protected]
1 parent 4d17c25 commit 63dffec

File tree

1 file changed

+4
-3
lines changed

1 file changed

+4
-3
lines changed

kernel/signal.c

+4-3
Original file line numberDiff line numberDiff line change
@@ -1959,14 +1959,15 @@ static void posixtimer_queue_sigqueue(struct sigqueue *q, struct task_struct *t,
19591959
*
19601960
* Where type is not PIDTYPE_PID, signals must be delivered to the
19611961
* process. In this case, prefer to deliver to current if it is in
1962-
* the same thread group as the target process, which avoids
1963-
* unnecessarily waking up a potentially idle task.
1962+
* the same thread group as the target process and its sighand is
1963+
* stable, which avoids unnecessarily waking up a potentially idle task.
19641964
*/
19651965
static inline struct task_struct *posixtimer_get_target(struct k_itimer *tmr)
19661966
{
19671967
struct task_struct *t = pid_task(tmr->it_pid, tmr->it_pid_type);
19681968

1969-
if (t && tmr->it_pid_type != PIDTYPE_PID && same_thread_group(t, current))
1969+
if (t && tmr->it_pid_type != PIDTYPE_PID &&
1970+
same_thread_group(t, current) && !current->exit_state)
19701971
t = current;
19711972
return t;
19721973
}

0 commit comments

Comments
 (0)