[PATCH 16/26] exit: Fix reporting a ptraced !reparented leader has exited

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

 



When a task exits and uses do_notify_parent to send tsk->exit_signal
or SIGCHLD this has one of two possible meanings.
- The ptraced task has exited
- The thread group has exited

Linux resolves this ambiguity by preferring the thread group exit
interpretation if it is possible.  As the exit of a thread group
containing a task is a superset of the exit of a task.

The code attempts to implement this in it's selection of signal
before calling do_notify_parent for a ptraced task.  Unfortunately
it fails to properly handle the case when the thread_group is still
running (but it's leader has exited).

Fix this for a ptraced child leader by skipping the notification
instead of changing the exit signal.  If we skip sending the signal in
exit_noitfy, when the last of the other threads are reaped
release_task will send the signal for us.

Signed-off-by: "Eric W. Biederman" <ebiederm@xxxxxxxxxxxx>
---
 kernel/exit.c | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/kernel/exit.c b/kernel/exit.c
index 85b34eff8807..72591eb5e361 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -639,7 +639,7 @@ static void forget_original_parent(struct task_struct *father,
  */
 static void exit_notify(struct task_struct *tsk, int group_dead)
 {
-	bool autoreap;
+	bool autoreap = true;
 	struct task_struct *p, *n;
 	LIST_HEAD(dead);
 
@@ -649,17 +649,12 @@ static void exit_notify(struct task_struct *tsk, int group_dead)
 	if (group_dead)
 		kill_orphaned_pgrp(tsk->group_leader, NULL);
 
-	if (unlikely(tsk->ptrace)) {
-		int sig = thread_group_leader(tsk) &&
-				thread_group_empty(tsk) &&
-				!ptrace_reparented(tsk) ?
-			tsk->exit_signal : SIGCHLD;
-		autoreap = do_notify_parent(tsk, sig);
-	} else if (thread_group_leader(tsk)) {
+	if (thread_group_leader(tsk) && !ptrace_reparented(tsk)) {
 		autoreap = thread_group_empty(tsk) &&
 			do_notify_parent(tsk, tsk->exit_signal);
-	} else {
-		autoreap = true;
+	}
+	else if (unlikely(tsk->ptrace)) {
+		autoreap = do_notify_parent(tsk, SIGCHLD);
 	}
 
 	tsk->exit_state = autoreap ? EXIT_DEAD : EXIT_ZOMBIE;
-- 
2.10.1

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



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux