Messages in this thread Patch in this message | | | Date | Wed, 22 Jun 2011 23:08:53 +0200 | From | Oleg Nesterov <> | Subject | [PATCH 3/8] __ptrace_detach: avoid task_detached(), check do_notify_parent() |
| |
__ptrace_detach() relies on the current obscure behaviour of do_notify_parent(tsk) which changes tsk->exit_signal if this child should be silently reaped. That is why we check task_detached(), it is true if the task is sub-thread, or it is the group_leader but its exit_signal was changed by do_notify_parent().
This is confusing, change the code to rely on !thread_group_leader() or the value returned by do_notify_parent().
Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---
kernel/ptrace.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-)
--- ptrace/kernel/ptrace.c~3_detach_ck_notify 2011-06-22 22:47:03.000000000 +0200 +++ ptrace/kernel/ptrace.c 2011-06-22 22:47:11.000000000 +0200 @@ -370,25 +370,28 @@ static int ignoring_children(struct sigh */ static bool __ptrace_detach(struct task_struct *tracer, struct task_struct *p) { + bool dead; + __ptrace_unlink(p); - if (p->exit_state == EXIT_ZOMBIE) { - if (!task_detached(p) && thread_group_empty(p)) { - if (!same_thread_group(p->real_parent, tracer)) - do_notify_parent(p, p->exit_signal); - else if (ignoring_children(tracer->sighand)) { - __wake_up_parent(p, tracer); - p->exit_signal = -1; - } - } - if (task_detached(p)) { - /* Mark it as in the process of being reaped. */ - p->exit_state = EXIT_DEAD; - return true; + if (p->exit_state != EXIT_ZOMBIE) + return false; + + dead = !thread_group_leader(p); + + if (!dead && thread_group_empty(p)) { + if (!same_thread_group(p->real_parent, tracer)) + dead = do_notify_parent(p, p->exit_signal); + else if (ignoring_children(tracer->sighand)) { + __wake_up_parent(p, tracer); + p->exit_signal = -1; + dead = true; } } - - return false; + /* Mark it as in the process of being reaped. */ + if (dead) + p->exit_state = EXIT_DEAD; + return dead; } static int ptrace_detach(struct task_struct *child, unsigned int data)
| |