diff options
Diffstat (limited to 'kernel/ptrace.c')
-rw-r--r-- | kernel/ptrace.c | 23 |
1 files changed, 3 insertions, 20 deletions
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 54e75226c2c4..1eb9d90c3af9 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
@@ -485,36 +485,19 @@ static int ptrace_detach(struct task_struct *child, unsigned int data) | |||
485 | 485 | ||
486 | /* | 486 | /* |
487 | * Detach all tasks we were using ptrace on. Called with tasklist held | 487 | * Detach all tasks we were using ptrace on. Called with tasklist held |
488 | * for writing, and returns with it held too. But note it can release | 488 | * for writing. |
489 | * and reacquire the lock. | ||
490 | */ | 489 | */ |
491 | void exit_ptrace(struct task_struct *tracer) | 490 | void exit_ptrace(struct task_struct *tracer, struct list_head *dead) |
492 | __releases(&tasklist_lock) | ||
493 | __acquires(&tasklist_lock) | ||
494 | { | 491 | { |
495 | struct task_struct *p, *n; | 492 | struct task_struct *p, *n; |
496 | LIST_HEAD(ptrace_dead); | ||
497 | |||
498 | if (likely(list_empty(&tracer->ptraced))) | ||
499 | return; | ||
500 | 493 | ||
501 | list_for_each_entry_safe(p, n, &tracer->ptraced, ptrace_entry) { | 494 | list_for_each_entry_safe(p, n, &tracer->ptraced, ptrace_entry) { |
502 | if (unlikely(p->ptrace & PT_EXITKILL)) | 495 | if (unlikely(p->ptrace & PT_EXITKILL)) |
503 | send_sig_info(SIGKILL, SEND_SIG_FORCED, p); | 496 | send_sig_info(SIGKILL, SEND_SIG_FORCED, p); |
504 | 497 | ||
505 | if (__ptrace_detach(tracer, p)) | 498 | if (__ptrace_detach(tracer, p)) |
506 | list_add(&p->ptrace_entry, &ptrace_dead); | 499 | list_add(&p->ptrace_entry, dead); |
507 | } | ||
508 | |||
509 | write_unlock_irq(&tasklist_lock); | ||
510 | BUG_ON(!list_empty(&tracer->ptraced)); | ||
511 | |||
512 | list_for_each_entry_safe(p, n, &ptrace_dead, ptrace_entry) { | ||
513 | list_del_init(&p->ptrace_entry); | ||
514 | release_task(p); | ||
515 | } | 500 | } |
516 | |||
517 | write_lock_irq(&tasklist_lock); | ||
518 | } | 501 | } |
519 | 502 | ||
520 | int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len) | 503 | int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len) |