aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/fs/exec.c b/fs/exec.c
index c7397c46ad6d..950ebd43cdc3 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -616,6 +616,15 @@ static int de_thread(struct task_struct *tsk)
616 kmem_cache_free(sighand_cachep, newsighand); 616 kmem_cache_free(sighand_cachep, newsighand);
617 return -EAGAIN; 617 return -EAGAIN;
618 } 618 }
619
620 /*
621 * child_reaper ignores SIGKILL, change it now.
622 * Reparenting needs write_lock on tasklist_lock,
623 * so it is safe to do it under read_lock.
624 */
625 if (unlikely(current->group_leader == child_reaper))
626 child_reaper = current;
627
619 zap_other_threads(current); 628 zap_other_threads(current);
620 read_unlock(&tasklist_lock); 629 read_unlock(&tasklist_lock);
621 630
@@ -699,22 +708,30 @@ static int de_thread(struct task_struct *tsk)
699 remove_parent(current); 708 remove_parent(current);
700 remove_parent(leader); 709 remove_parent(leader);
701 710
702 switch_exec_pids(leader, current); 711
712 /* Become a process group leader with the old leader's pid.
713 * Note: The old leader also uses thispid until release_task
714 * is called. Odd but simple and correct.
715 */
716 detach_pid(current, PIDTYPE_PID);
717 current->pid = leader->pid;
718 attach_pid(current, PIDTYPE_PID, current->pid);
719 attach_pid(current, PIDTYPE_PGID, current->signal->pgrp);
720 attach_pid(current, PIDTYPE_SID, current->signal->session);
721 list_add_tail(&current->tasks, &init_task.tasks);
703 722
704 current->parent = current->real_parent = leader->real_parent; 723 current->parent = current->real_parent = leader->real_parent;
705 leader->parent = leader->real_parent = child_reaper; 724 leader->parent = leader->real_parent = child_reaper;
706 current->group_leader = current; 725 current->group_leader = current;
707 leader->group_leader = leader; 726 leader->group_leader = leader;
708 727
709 add_parent(current, current->parent); 728 add_parent(current);
710 add_parent(leader, leader->parent); 729 add_parent(leader);
711 if (ptrace) { 730 if (ptrace) {
712 current->ptrace = ptrace; 731 current->ptrace = ptrace;
713 __ptrace_link(current, parent); 732 __ptrace_link(current, parent);
714 } 733 }
715 734
716 list_del(&current->tasks);
717 list_add_tail(&current->tasks, &init_task.tasks);
718 current->exit_signal = SIGCHLD; 735 current->exit_signal = SIGCHLD;
719 736
720 BUG_ON(leader->exit_state != EXIT_ZOMBIE); 737 BUG_ON(leader->exit_state != EXIT_ZOMBIE);
@@ -751,7 +768,6 @@ no_thread_group:
751 /* 768 /*
752 * Move our state over to newsighand and switch it in. 769 * Move our state over to newsighand and switch it in.
753 */ 770 */
754 spin_lock_init(&newsighand->siglock);
755 atomic_set(&newsighand->count, 1); 771 atomic_set(&newsighand->count, 1);
756 memcpy(newsighand->action, oldsighand->action, 772 memcpy(newsighand->action, oldsighand->action,
757 sizeof(newsighand->action)); 773 sizeof(newsighand->action));
@@ -768,7 +784,7 @@ no_thread_group:
768 write_unlock_irq(&tasklist_lock); 784 write_unlock_irq(&tasklist_lock);
769 785
770 if (atomic_dec_and_test(&oldsighand->count)) 786 if (atomic_dec_and_test(&oldsighand->count))
771 sighand_free(oldsighand); 787 kmem_cache_free(sighand_cachep, oldsighand);
772 } 788 }
773 789
774 BUG_ON(!thread_group_leader(current)); 790 BUG_ON(!thread_group_leader(current));