Oleg Nesterov ee7c82da83 wait_task_stopped: simplify and fix races with SIGCONT/SIGKILL/untrace
wait_task_stopped() has multiple races with SIGCONT/SIGKILL.  tasklist_lock
does not pin the child in TASK_TRACED/TASK_STOPPED stated, almost all info
reported (including exit_code) may be wrong.

In fact, the code under write_lock_irq(tasklist_lock) is not safe.  The child
may be PTRACE_DETACH'ed at this time by another subthread, in that case it is
possible we are no longer its ->parent.

Change wait_task_stopped() to take ->siglock before inspecting the task.  This
guarantees that the child can't resume and (for example) clear its
->exit_code, so we don't need to use xchg(&p->exit_code) and re-check.  The
only exception is ptrace_stop() which changes ->state and ->exit_code without
->siglock held during abort.  But this can only happen if both the tracer and
the tracee are dying (coredump is in progress), we don't care.

With this patch wait_task_stopped() doesn't move the child to the end of
the ->parent list on success.  This optimization could be restored, but
in that case we have to take write_lock(tasklist) and do some nasty
checks.

Also change the do_wait() since we don't return EAGAIN any longer.

[akpm@linux-foundation.org: fix up after Willy renamed everything]
Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
Cc: Roland McGrath <roland@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-02-08 09:22:26 -08:00
..
2008-02-07 01:27:17 -05:00
2008-01-07 14:55:37 -08:00
2007-10-21 02:37:45 -04:00
2007-10-21 02:37:45 -04:00
2008-02-07 08:42:22 -08:00
2007-10-18 14:37:24 -07:00
2008-02-07 08:42:18 -08:00
2008-02-05 09:44:07 -08:00
2007-10-18 14:37:26 -07:00
2008-01-25 21:08:29 +01:00
2007-07-16 09:05:50 -07:00
2008-01-25 21:08:34 +01:00
2007-12-06 17:37:59 -05:00
2008-02-05 09:44:07 -08:00
2008-01-25 21:08:33 +01:00
2008-01-25 21:08:24 +01:00
2008-01-25 21:08:24 +01:00
2008-01-25 21:08:25 +01:00
2008-02-06 10:41:07 -08:00
2007-07-16 09:05:49 -07:00
2007-07-16 09:05:50 -07:00
2008-02-02 14:27:45 +11:00
2008-01-30 13:31:20 +01:00
2008-02-06 10:41:02 -08:00
2008-02-06 10:41:08 -08:00
2008-02-05 09:44:07 -08:00
2008-02-06 10:41:00 -08:00
2007-12-06 17:34:36 -05:00