diff options
Diffstat (limited to 'fs/exec.c')
| -rw-r--r-- | fs/exec.c | 39 |
1 files changed, 23 insertions, 16 deletions
| @@ -630,10 +630,9 @@ static inline int de_thread(struct task_struct *tsk) | |||
| 630 | /* | 630 | /* |
| 631 | * Account for the thread group leader hanging around: | 631 | * Account for the thread group leader hanging around: |
| 632 | */ | 632 | */ |
| 633 | count = 2; | 633 | count = 1; |
| 634 | if (thread_group_leader(current)) | 634 | if (!thread_group_leader(current)) { |
| 635 | count = 1; | 635 | count = 2; |
| 636 | else { | ||
| 637 | /* | 636 | /* |
| 638 | * The SIGALRM timer survives the exec, but needs to point | 637 | * The SIGALRM timer survives the exec, but needs to point |
| 639 | * at us as the new group leader now. We have a race with | 638 | * at us as the new group leader now. We have a race with |
| @@ -642,8 +641,10 @@ static inline int de_thread(struct task_struct *tsk) | |||
| 642 | * before we can safely let the old group leader die. | 641 | * before we can safely let the old group leader die. |
| 643 | */ | 642 | */ |
| 644 | sig->real_timer.data = (unsigned long)current; | 643 | sig->real_timer.data = (unsigned long)current; |
| 644 | spin_unlock_irq(lock); | ||
| 645 | if (del_timer_sync(&sig->real_timer)) | 645 | if (del_timer_sync(&sig->real_timer)) |
| 646 | add_timer(&sig->real_timer); | 646 | add_timer(&sig->real_timer); |
| 647 | spin_lock_irq(lock); | ||
| 647 | } | 648 | } |
| 648 | while (atomic_read(&sig->count) > count) { | 649 | while (atomic_read(&sig->count) > count) { |
| 649 | sig->group_exit_task = current; | 650 | sig->group_exit_task = current; |
| @@ -655,7 +656,6 @@ static inline int de_thread(struct task_struct *tsk) | |||
| 655 | } | 656 | } |
| 656 | sig->group_exit_task = NULL; | 657 | sig->group_exit_task = NULL; |
| 657 | sig->notify_count = 0; | 658 | sig->notify_count = 0; |
| 658 | sig->real_timer.data = (unsigned long)current; | ||
| 659 | spin_unlock_irq(lock); | 659 | spin_unlock_irq(lock); |
| 660 | 660 | ||
| 661 | /* | 661 | /* |
| @@ -1417,19 +1417,16 @@ static void zap_threads (struct mm_struct *mm) | |||
| 1417 | static void coredump_wait(struct mm_struct *mm) | 1417 | static void coredump_wait(struct mm_struct *mm) |
| 1418 | { | 1418 | { |
| 1419 | DECLARE_COMPLETION(startup_done); | 1419 | DECLARE_COMPLETION(startup_done); |
| 1420 | int core_waiters; | ||
| 1420 | 1421 | ||
| 1421 | mm->core_waiters++; /* let other threads block */ | ||
| 1422 | mm->core_startup_done = &startup_done; | 1422 | mm->core_startup_done = &startup_done; |
| 1423 | 1423 | ||
| 1424 | /* give other threads a chance to run: */ | ||
| 1425 | yield(); | ||
| 1426 | |||
| 1427 | zap_threads(mm); | 1424 | zap_threads(mm); |
| 1428 | if (--mm->core_waiters) { | 1425 | core_waiters = mm->core_waiters; |
| 1429 | up_write(&mm->mmap_sem); | 1426 | up_write(&mm->mmap_sem); |
| 1427 | |||
| 1428 | if (core_waiters) | ||
| 1430 | wait_for_completion(&startup_done); | 1429 | wait_for_completion(&startup_done); |
| 1431 | } else | ||
| 1432 | up_write(&mm->mmap_sem); | ||
| 1433 | BUG_ON(mm->core_waiters); | 1430 | BUG_ON(mm->core_waiters); |
| 1434 | } | 1431 | } |
| 1435 | 1432 | ||
| @@ -1463,11 +1460,21 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) | |||
| 1463 | current->fsuid = 0; /* Dump root private */ | 1460 | current->fsuid = 0; /* Dump root private */ |
| 1464 | } | 1461 | } |
| 1465 | mm->dumpable = 0; | 1462 | mm->dumpable = 0; |
| 1466 | init_completion(&mm->core_done); | 1463 | |
| 1464 | retval = -EAGAIN; | ||
| 1467 | spin_lock_irq(¤t->sighand->siglock); | 1465 | spin_lock_irq(¤t->sighand->siglock); |
| 1468 | current->signal->flags = SIGNAL_GROUP_EXIT; | 1466 | if (!(current->signal->flags & SIGNAL_GROUP_EXIT)) { |
| 1469 | current->signal->group_exit_code = exit_code; | 1467 | current->signal->flags = SIGNAL_GROUP_EXIT; |
| 1468 | current->signal->group_exit_code = exit_code; | ||
| 1469 | retval = 0; | ||
| 1470 | } | ||
| 1470 | spin_unlock_irq(¤t->sighand->siglock); | 1471 | spin_unlock_irq(¤t->sighand->siglock); |
| 1472 | if (retval) { | ||
| 1473 | up_write(&mm->mmap_sem); | ||
| 1474 | goto fail; | ||
| 1475 | } | ||
| 1476 | |||
| 1477 | init_completion(&mm->core_done); | ||
| 1471 | coredump_wait(mm); | 1478 | coredump_wait(mm); |
| 1472 | 1479 | ||
| 1473 | /* | 1480 | /* |
