diff options
| -rw-r--r-- | kernel/ptrace.c | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index e18966c1c0da..66a28bd71ef6 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
| @@ -370,25 +370,28 @@ static int ignoring_children(struct sighand_struct *sigh) | |||
| 370 | */ | 370 | */ |
| 371 | static bool __ptrace_detach(struct task_struct *tracer, struct task_struct *p) | 371 | static bool __ptrace_detach(struct task_struct *tracer, struct task_struct *p) |
| 372 | { | 372 | { |
| 373 | bool dead; | ||
| 374 | |||
| 373 | __ptrace_unlink(p); | 375 | __ptrace_unlink(p); |
| 374 | 376 | ||
| 375 | if (p->exit_state == EXIT_ZOMBIE) { | 377 | if (p->exit_state != EXIT_ZOMBIE) |
| 376 | if (!task_detached(p) && thread_group_empty(p)) { | 378 | return false; |
| 377 | if (!same_thread_group(p->real_parent, tracer)) | 379 | |
| 378 | do_notify_parent(p, p->exit_signal); | 380 | dead = !thread_group_leader(p); |
| 379 | else if (ignoring_children(tracer->sighand)) { | 381 | |
| 380 | __wake_up_parent(p, tracer); | 382 | if (!dead && thread_group_empty(p)) { |
| 381 | p->exit_signal = -1; | 383 | if (!same_thread_group(p->real_parent, tracer)) |
| 382 | } | 384 | dead = do_notify_parent(p, p->exit_signal); |
| 383 | } | 385 | else if (ignoring_children(tracer->sighand)) { |
| 384 | if (task_detached(p)) { | 386 | __wake_up_parent(p, tracer); |
| 385 | /* Mark it as in the process of being reaped. */ | 387 | p->exit_signal = -1; |
| 386 | p->exit_state = EXIT_DEAD; | 388 | dead = true; |
| 387 | return true; | ||
| 388 | } | 389 | } |
| 389 | } | 390 | } |
| 390 | 391 | /* Mark it as in the process of being reaped. */ | |
| 391 | return false; | 392 | if (dead) |
| 393 | p->exit_state = EXIT_DEAD; | ||
| 394 | return dead; | ||
| 392 | } | 395 | } |
| 393 | 396 | ||
| 394 | static int ptrace_detach(struct task_struct *child, unsigned int data) | 397 | static int ptrace_detach(struct task_struct *child, unsigned int data) |
