]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - kernel/exit.c
[PATCH] wait4 PTRACE_ATTACH race fix
[mirror_ubuntu-artful-kernel.git] / kernel / exit.c
index 3b25b182d2be35cfe8ddc69c53a908da96ce5aec..2d39ccc367e69de0243ed17f3f342efdcf267482 100644 (file)
@@ -783,10 +783,6 @@ static void exit_notify(struct task_struct *tsk)
        /* If the process is dead, release it - nobody will wait for it */
        if (state == EXIT_DEAD)
                release_task(tsk);
-
-       /* PF_DEAD causes final put_task_struct after we schedule. */
-       preempt_disable();
-       tsk->flags |= PF_DEAD;
 }
 
 fastcall NORET_TYPE void do_exit(long code)
@@ -839,7 +835,10 @@ fastcall NORET_TYPE void do_exit(long code)
                                preempt_count());
 
        acct_update_integrals(tsk);
-       update_mem_hiwater(tsk);
+       if (tsk->mm) {
+               update_hiwater_rss(tsk->mm);
+               update_hiwater_vm(tsk->mm);
+       }
        group_dead = atomic_dec_and_test(&tsk->signal->live);
        if (group_dead) {
                del_timer_sync(&tsk->signal->real_timer);
@@ -870,7 +869,11 @@ fastcall NORET_TYPE void do_exit(long code)
        tsk->mempolicy = NULL;
 #endif
 
-       BUG_ON(!(current->flags & PF_DEAD));
+       /* PF_DEAD causes final put_task_struct after we schedule. */
+       preempt_disable();
+       BUG_ON(tsk->flags & PF_DEAD);
+       tsk->flags |= PF_DEAD;
+
        schedule();
        BUG();
        /* Avoid "noreturn function does return".  */
@@ -1380,6 +1383,15 @@ repeat:
 
                        switch (p->state) {
                        case TASK_TRACED:
+                               /*
+                                * When we hit the race with PTRACE_ATTACH,
+                                * we will not report this child.  But the
+                                * race means it has not yet been moved to
+                                * our ptrace_children list, so we need to
+                                * set the flag here to avoid a spurious ECHILD
+                                * when the race happens with the only child.
+                                */
+                               flag = 1;
                                if (!my_ptrace_child(p))
                                        continue;
                                /*FALLTHROUGH*/