+ wait-fix-reparent_leader-vs-exit_dead-exit_zombie-race.patch added to -mm tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Subject: + wait-fix-reparent_leader-vs-exit_dead-exit_zombie-race.patch added to -mm tree
To: oleg@xxxxxxxxxx,jan.kratochvil@xxxxxxxxxx,lpoetter@xxxxxxxxxx,mschmidt@xxxxxxxxxx,roland@xxxxxxxxxxxxx,stable@xxxxxxxxxxxxxxx,tj@xxxxxxxxxx,viro@xxxxxxxxxxxxxxxxxx
From: akpm@xxxxxxxxxxxxxxxxxxxx
Date: Fri, 21 Feb 2014 13:39:16 -0800


The patch titled
     Subject: wait: fix reparent_leader() vs EXIT_DEAD->EXIT_ZOMBIE race
has been added to the -mm tree.  Its filename is
     wait-fix-reparent_leader-vs-exit_dead-exit_zombie-race.patch

This patch should soon appear at
    http://ozlabs.org/~akpm/mmots/broken-out/wait-fix-reparent_leader-vs-exit_dead-exit_zombie-race.patch
and later at
    http://ozlabs.org/~akpm/mmotm/broken-out/wait-fix-reparent_leader-vs-exit_dead-exit_zombie-race.patch

Before you just go and hit "reply", please:
   a) Consider who else should be cc'ed
   b) Prefer to cc a suitable mailing list as well
   c) Ideally: find the original patch on the mailing list and do a
      reply-to-all to that, adding suitable additional cc's

*** Remember to use Documentation/SubmitChecklist when testing your code ***

The -mm tree is included into linux-next and is updated
there every 3-4 working days

------------------------------------------------------
From: Oleg Nesterov <oleg@xxxxxxxxxx>
Subject: wait: fix reparent_leader() vs EXIT_DEAD->EXIT_ZOMBIE race

wait_task_zombie() first does EXIT_ZOMBIE->EXIT_DEAD transition and drops
tasklist_lock.  If this task is not the natural child and it is traced, we
change its state back to EXIT_ZOMBIE for ->real_parent.

The last transition is racy, this is even documented in 50b8d257486a
"ptrace: partially fix the do_wait(WEXITED) vs EXIT_DEAD->EXIT_ZOMBIE
race".  wait_consider_task() tries to detect this transition and clear
->notask_error but we can't rely on ptrace_reparented(), debugger can exit
and do ptrace_unlink() before its sub-thread sets EXIT_ZOMBIE.

And there is another problem which were missed before: this transition can
also race with reparent_leader() which doesn't reset >exit_signal if
EXIT_DEAD, assuming that this task must be reaped by someone else.  So the
tracee can be re-parented with ->exit_signal != SIGCHLD, and if /sbin/init
doesn't use __WALL it becomes unreapable.

Change reparent_leader() to update ->exit_signal even if EXIT_DEAD.  Note:
this is the simple temporary hack for -stable, it doesn't try to solve all
problems, it will be reverted by the next changes.

Signed-off-by: Oleg Nesterov <oleg@xxxxxxxxxx>
Reported-by: Jan Kratochvil <jan.kratochvil@xxxxxxxxxx>
Reported-by: Michal Schmidt <mschmidt@xxxxxxxxxx>
Tested-by: Michal Schmidt <mschmidt@xxxxxxxxxx>
Cc: Al Viro <viro@xxxxxxxxxxxxxxxxxx>
Cc: Lennart Poettering <lpoetter@xxxxxxxxxx>
Cc: Roland McGrath <roland@xxxxxxxxxxxxx>
Cc: Tejun Heo <tj@xxxxxxxxxx>
Cc: <stable@xxxxxxxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
---

 kernel/exit.c |   15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff -puN kernel/exit.c~wait-fix-reparent_leader-vs-exit_dead-exit_zombie-race kernel/exit.c
--- a/kernel/exit.c~wait-fix-reparent_leader-vs-exit_dead-exit_zombie-race
+++ a/kernel/exit.c
@@ -560,9 +560,6 @@ static void reparent_leader(struct task_
 				struct list_head *dead)
 {
 	list_move_tail(&p->sibling, &p->real_parent->children);
-
-	if (p->exit_state == EXIT_DEAD)
-		return;
 	/*
 	 * If this is a threaded reparent there is no need to
 	 * notify anyone anything has happened.
@@ -570,9 +567,19 @@ static void reparent_leader(struct task_
 	if (same_thread_group(p->real_parent, father))
 		return;
 
-	/* We don't want people slaying init.  */
+	/*
+	 * We don't want people slaying init.
+	 *
+	 * Note: we do this even if it is EXIT_DEAD, wait_task_zombie()
+	 * can change ->exit_state to EXIT_ZOMBIE. If this is the final
+	 * state, do_notify_parent() was already called and ->exit_signal
+	 * doesn't matter.
+	 */
 	p->exit_signal = SIGCHLD;
 
+	if (p->exit_state == EXIT_DEAD)
+		return;
+
 	/* If it has exited notify the new parent about this child's death. */
 	if (!p->ptrace &&
 	    p->exit_state == EXIT_ZOMBIE && thread_group_empty(p)) {
_

Patches currently in -mm which might be from oleg@xxxxxxxxxx are

kthread-ensure-locality-of-task_struct-allocations.patch
wait-fix-reparent_leader-vs-exit_dead-exit_zombie-race.patch
wait-introduce-exit_trace-to-avoid-the-racy-exit_dead-exit_zombie-transition.patch
wait-use-exit_trace-only-if-thread_group_leaderzombie.patch
wait-completely-ignore-the-exit_dead-tasks.patch
wait-swap-exit_zombie-and-exit_dead-to-hide-exit_trace-from-user-space.patch
linux-next.patch

--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]