Skip to content

Commit

Permalink
posix-timers: sys_timer_create: remove the buggy PF_EXITING check
Browse files Browse the repository at this point in the history
sys_timer_create() return -EINVAL if the target thread has PF_EXITING.

This doesn't really make sense, the sub-thread can die right after unlock.
And in fact, this is just wrong.  Without SIGEV_THREAD_ID good_sigevent()
returns ->group_leader, and it is very possible that the leader is already
dead.  This is OK, we shouldn't return the error in this case.

Remove this check and the comment.  Note that the "process" was found
under tasklist_lock, it must have ->sighand != NULL.

Also, remove a couple of unneeded initializations.

Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
Cc: mingo@elte.hu
Cc: Roland McGrath <roland@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
  • Loading branch information
Oleg Nesterov authored and Thomas Gleixner committed Sep 24, 2008
1 parent 918fc03 commit 2cd499e
Showing 1 changed file with 7 additions and 27 deletions.
34 changes: 7 additions & 27 deletions kernel/posix-timers.c
Original file line number Diff line number Diff line change
Expand Up @@ -460,9 +460,9 @@ sys_timer_create(const clockid_t which_clock,
timer_t __user * created_timer_id)
{
int error = 0;
struct k_itimer *new_timer = NULL;
struct k_itimer *new_timer;
int new_timer_id;
struct task_struct *process = NULL;
struct task_struct *process;
unsigned long flags;
sigevent_t event;
int it_id_set = IT_ID_NOT_SET;
Expand Down Expand Up @@ -523,32 +523,12 @@ sys_timer_create(const clockid_t which_clock,

read_lock(&tasklist_lock);
if ((process = good_sigevent(&event))) {
/*
* We may be setting up this process for another
* thread. It may be exiting. To catch this
* case the we check the PF_EXITING flag. If
* the flag is not set, the siglock will catch
* him before it is too late (in exit_itimers).
*
* The exec case is a bit more invloved but easy
* to code. If the process is in our thread
* group (and it must be or we would not allow
* it here) and is doing an exec, it will cause
* us to be killed. In this case it will wait
* for us to die which means we can finish this
* linkage with our last gasp. I.e. no code :)
*/
get_task_struct(process);
spin_lock_irqsave(&process->sighand->siglock, flags);
if (!(process->flags & PF_EXITING)) {
get_task_struct(process);
new_timer->it_process = process;
list_add(&new_timer->list,
&process->signal->posix_timers);
spin_unlock_irqrestore(&process->sighand->siglock, flags);
} else {
spin_unlock_irqrestore(&process->sighand->siglock, flags);
process = NULL;
}
new_timer->it_process = process;
list_add(&new_timer->list,
&process->signal->posix_timers);
spin_unlock_irqrestore(&process->sighand->siglock, flags);
}
read_unlock(&tasklist_lock);
if (!process) {
Expand Down

0 comments on commit 2cd499e

Please sign in to comment.