diff options
-rw-r--r-- | fs/exec.c | 12 |
1 files changed, 12 insertions, 0 deletions
@@ -642,6 +642,18 @@ static inline int de_thread(struct task_struct *tsk) | |||
642 | count = 2; | 642 | count = 2; |
643 | if (thread_group_leader(current)) | 643 | if (thread_group_leader(current)) |
644 | count = 1; | 644 | count = 1; |
645 | else { | ||
646 | /* | ||
647 | * The SIGALRM timer survives the exec, but needs to point | ||
648 | * at us as the new group leader now. We have a race with | ||
649 | * a timer firing now getting the old leader, so we need to | ||
650 | * synchronize with any firing (by calling del_timer_sync) | ||
651 | * before we can safely let the old group leader die. | ||
652 | */ | ||
653 | sig->real_timer.data = (unsigned long)current; | ||
654 | if (del_timer_sync(&sig->real_timer)) | ||
655 | add_timer(&sig->real_timer); | ||
656 | } | ||
645 | while (atomic_read(&sig->count) > count) { | 657 | while (atomic_read(&sig->count) > count) { |
646 | sig->group_exit_task = current; | 658 | sig->group_exit_task = current; |
647 | sig->notify_count = count; | 659 | sig->notify_count = count; |