From 056ffaadc8a7197d681e12b2da9ab61ca68e9a97 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 14 Dec 2003 02:28:27 -0800 Subject: [PATCH] Fix thread group leader zombie leak Petr Vandrovec noticed a problem where the thread group leader would not be properly reaped if the parent of the thread group was ignoring SIGCHLD, and the thread group leader had exited before the last sub-thread. Fixed by Ingo Molnar. --- kernel/exit.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/kernel/exit.c b/kernel/exit.c index 202d7eaf3245f..1f7e7545e1d05 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -49,9 +49,11 @@ static void __unhash_process(struct task_struct *p) void release_task(struct task_struct * p) { + int zap_leader; task_t *leader; struct dentry *proc_dentry; - + +repeat: BUG_ON(p->state < TASK_ZOMBIE); atomic_dec(&p->user->processes); @@ -70,10 +72,21 @@ void release_task(struct task_struct * p) * group, and the leader is zombie, then notify the * group leader's parent process. (if it wants notification.) */ + zap_leader = 0; leader = p->group_leader; - if (leader != p && thread_group_empty(leader) && - leader->state == TASK_ZOMBIE && leader->exit_signal != -1) + if (leader != p && thread_group_empty(leader) && leader->state == TASK_ZOMBIE) { + BUG_ON(leader->exit_signal == -1); do_notify_parent(leader, leader->exit_signal); + /* + * If we were the last child thread and the leader has + * exited already, and the leader's parent ignores SIGCHLD, + * then we are the one who should release the leader. + * + * do_notify_parent() will have marked it self-reaping in + * that case. + */ + zap_leader = (leader->exit_signal == -1); + } p->parent->cutime += p->utime + p->cutime; p->parent->cstime += p->stime + p->cstime; @@ -88,6 +101,10 @@ void release_task(struct task_struct * p) proc_pid_flush(proc_dentry); release_thread(p); put_task_struct(p); + + p = leader; + if (unlikely(zap_leader)) + goto repeat; } /* we are using it only for SMP init */ -- 2.53.0