[PATCH] fix do_wait() vs exec() race

From: Oleg Nesterov
Date: Tue Nov 22 2005 - 13:05:51 EST


When non-leader thread does exec, de_thread adds old leader to the
init's ->children list in EXIT_ZOMBIE state and drops tasklist_lock.

This means that release_task(leader) in de_thread() is racy vs do_wait()
from init task.

I think de_thread() should set old leader's state to EXIT_DEAD instead.

Signed-off-by: Oleg Nesterov <oleg@xxxxxxxxxx>

--- 2.6.15-rc2/fs/exec.c~ 2005-11-22 19:35:31.000000000 +0300
+++ 2.6.15-rc2/fs/exec.c 2005-11-23 00:49:23.000000000 +0300
@@ -668,7 +668,7 @@ static inline int de_thread(struct task_
if (!thread_group_leader(current)) {
struct task_struct *parent;
struct dentry *proc_dentry1, *proc_dentry2;
- unsigned long exit_state, ptrace;
+ unsigned long ptrace;

/*
* Wait for the thread group leader to be a zombie.
@@ -726,15 +726,15 @@ static inline int de_thread(struct task_
list_del(&current->tasks);
list_add_tail(&current->tasks, &init_task.tasks);
current->exit_signal = SIGCHLD;
- exit_state = leader->exit_state;
+
+ BUG_ON(leader->exit_state != EXIT_ZOMBIE);
+ leader->exit_state = EXIT_DEAD;

write_unlock_irq(&tasklist_lock);
spin_unlock(&leader->proc_lock);
spin_unlock(&current->proc_lock);
proc_pid_flush(proc_dentry1);
proc_pid_flush(proc_dentry2);
-
- BUG_ON(exit_state != EXIT_ZOMBIE);
}

/*
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/