aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 4e834f16d9da..b4e5b8a9216a 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -772,7 +772,6 @@ static int de_thread(struct task_struct *tsk)
772 struct signal_struct *sig = tsk->signal; 772 struct signal_struct *sig = tsk->signal;
773 struct sighand_struct *oldsighand = tsk->sighand; 773 struct sighand_struct *oldsighand = tsk->sighand;
774 spinlock_t *lock = &oldsighand->siglock; 774 spinlock_t *lock = &oldsighand->siglock;
775 struct task_struct *leader = NULL;
776 int count; 775 int count;
777 776
778 if (thread_group_empty(tsk)) 777 if (thread_group_empty(tsk))
@@ -810,7 +809,7 @@ static int de_thread(struct task_struct *tsk)
810 * and to assume its PID: 809 * and to assume its PID:
811 */ 810 */
812 if (!thread_group_leader(tsk)) { 811 if (!thread_group_leader(tsk)) {
813 leader = tsk->group_leader; 812 struct task_struct *leader = tsk->group_leader;
814 813
815 sig->notify_count = -1; /* for exit_notify() */ 814 sig->notify_count = -1; /* for exit_notify() */
816 for (;;) { 815 for (;;) {
@@ -862,8 +861,9 @@ static int de_thread(struct task_struct *tsk)
862 861
863 BUG_ON(leader->exit_state != EXIT_ZOMBIE); 862 BUG_ON(leader->exit_state != EXIT_ZOMBIE);
864 leader->exit_state = EXIT_DEAD; 863 leader->exit_state = EXIT_DEAD;
865
866 write_unlock_irq(&tasklist_lock); 864 write_unlock_irq(&tasklist_lock);
865
866 release_task(leader);
867 } 867 }
868 868
869 sig->group_exit_task = NULL; 869 sig->group_exit_task = NULL;
@@ -872,8 +872,6 @@ static int de_thread(struct task_struct *tsk)
872no_thread_group: 872no_thread_group:
873 exit_itimers(sig); 873 exit_itimers(sig);
874 flush_itimer_signals(); 874 flush_itimer_signals();
875 if (leader)
876 release_task(leader);
877 875
878 if (atomic_read(&oldsighand->count) != 1) { 876 if (atomic_read(&oldsighand->count) != 1) {
879 struct sighand_struct *newsighand; 877 struct sighand_struct *newsighand;
@@ -1159,6 +1157,7 @@ EXPORT_SYMBOL(remove_arg_zero);
1159 */ 1157 */
1160int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) 1158int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
1161{ 1159{
1160 unsigned int depth = bprm->recursion_depth;
1162 int try,retval; 1161 int try,retval;
1163 struct linux_binfmt *fmt; 1162 struct linux_binfmt *fmt;
1164#ifdef __alpha__ 1163#ifdef __alpha__
@@ -1219,8 +1218,15 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
1219 continue; 1218 continue;
1220 read_unlock(&binfmt_lock); 1219 read_unlock(&binfmt_lock);
1221 retval = fn(bprm, regs); 1220 retval = fn(bprm, regs);
1221 /*
1222 * Restore the depth counter to its starting value
1223 * in this call, so we don't have to rely on every
1224 * load_binary function to restore it on return.
1225 */
1226 bprm->recursion_depth = depth;
1222 if (retval >= 0) { 1227 if (retval >= 0) {
1223 tracehook_report_exec(fmt, bprm, regs); 1228 if (depth == 0)
1229 tracehook_report_exec(fmt, bprm, regs);
1224 put_binfmt(fmt); 1230 put_binfmt(fmt);
1225 allow_write_access(bprm->file); 1231 allow_write_access(bprm->file);
1226 if (bprm->file) 1232 if (bprm->file)