diff options
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 18 |
1 files changed, 12 insertions, 6 deletions
@@ -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) | |||
872 | no_thread_group: | 872 | no_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 | */ |
1160 | int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) | 1158 | int 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) |