aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c39
1 files changed, 27 insertions, 12 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 0b515ac53134..950ebd43cdc3 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -127,7 +127,7 @@ asmlinkage long sys_uselib(const char __user * library)
127 struct nameidata nd; 127 struct nameidata nd;
128 int error; 128 int error;
129 129
130 error = __user_path_lookup_open(library, LOOKUP_FOLLOW, &nd, FMODE_READ); 130 error = __user_path_lookup_open(library, LOOKUP_FOLLOW, &nd, FMODE_READ|FMODE_EXEC);
131 if (error) 131 if (error)
132 goto out; 132 goto out;
133 133
@@ -477,7 +477,7 @@ struct file *open_exec(const char *name)
477 int err; 477 int err;
478 struct file *file; 478 struct file *file;
479 479
480 err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd, FMODE_READ); 480 err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd, FMODE_READ|FMODE_EXEC);
481 file = ERR_PTR(err); 481 file = ERR_PTR(err);
482 482
483 if (!err) { 483 if (!err) {
@@ -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
@@ -632,7 +641,7 @@ static int de_thread(struct task_struct *tsk)
632 * synchronize with any firing (by calling del_timer_sync) 641 * synchronize with any firing (by calling del_timer_sync)
633 * before we can safely let the old group leader die. 642 * before we can safely let the old group leader die.
634 */ 643 */
635 sig->real_timer.data = current; 644 sig->tsk = current;
636 spin_unlock_irq(lock); 645 spin_unlock_irq(lock);
637 if (hrtimer_cancel(&sig->real_timer)) 646 if (hrtimer_cancel(&sig->real_timer))
638 hrtimer_restart(&sig->real_timer); 647 hrtimer_restart(&sig->real_timer);
@@ -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));
@@ -1143,10 +1159,9 @@ int do_execve(char * filename,
1143 int i; 1159 int i;
1144 1160
1145 retval = -ENOMEM; 1161 retval = -ENOMEM;
1146 bprm = kmalloc(sizeof(*bprm), GFP_KERNEL); 1162 bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
1147 if (!bprm) 1163 if (!bprm)
1148 goto out_ret; 1164 goto out_ret;
1149 memset(bprm, 0, sizeof(*bprm));
1150 1165
1151 file = open_exec(filename); 1166 file = open_exec(filename);
1152 retval = PTR_ERR(file); 1167 retval = PTR_ERR(file);