diff options
Diffstat (limited to 'fs/binfmt_elf.c')
-rw-r--r-- | fs/binfmt_elf.c | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index a27e42bf3400..295cbaa0e58a 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -148,6 +148,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, | |||
148 | elf_addr_t *elf_info; | 148 | elf_addr_t *elf_info; |
149 | int ei_index = 0; | 149 | int ei_index = 0; |
150 | struct task_struct *tsk = current; | 150 | struct task_struct *tsk = current; |
151 | struct vm_area_struct *vma; | ||
151 | 152 | ||
152 | /* | 153 | /* |
153 | * If this architecture has a platform capability string, copy it | 154 | * If this architecture has a platform capability string, copy it |
@@ -234,6 +235,15 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, | |||
234 | sp = (elf_addr_t __user *)bprm->p; | 235 | sp = (elf_addr_t __user *)bprm->p; |
235 | #endif | 236 | #endif |
236 | 237 | ||
238 | |||
239 | /* | ||
240 | * Grow the stack manually; some architectures have a limit on how | ||
241 | * far ahead a user-space access may be in order to grow the stack. | ||
242 | */ | ||
243 | vma = find_extend_vma(current->mm, bprm->p); | ||
244 | if (!vma) | ||
245 | return -EFAULT; | ||
246 | |||
237 | /* Now, let's put argc (and argv, envp if appropriate) on the stack */ | 247 | /* Now, let's put argc (and argv, envp if appropriate) on the stack */ |
238 | if (__put_user(argc, sp++)) | 248 | if (__put_user(argc, sp++)) |
239 | return -EFAULT; | 249 | return -EFAULT; |
@@ -254,8 +264,8 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, | |||
254 | size_t len; | 264 | size_t len; |
255 | if (__put_user((elf_addr_t)p, argv++)) | 265 | if (__put_user((elf_addr_t)p, argv++)) |
256 | return -EFAULT; | 266 | return -EFAULT; |
257 | len = strnlen_user((void __user *)p, PAGE_SIZE*MAX_ARG_PAGES); | 267 | len = strnlen_user((void __user *)p, MAX_ARG_STRLEN); |
258 | if (!len || len > PAGE_SIZE*MAX_ARG_PAGES) | 268 | if (!len || len > MAX_ARG_STRLEN) |
259 | return 0; | 269 | return 0; |
260 | p += len; | 270 | p += len; |
261 | } | 271 | } |
@@ -266,8 +276,8 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, | |||
266 | size_t len; | 276 | size_t len; |
267 | if (__put_user((elf_addr_t)p, envp++)) | 277 | if (__put_user((elf_addr_t)p, envp++)) |
268 | return -EFAULT; | 278 | return -EFAULT; |
269 | len = strnlen_user((void __user *)p, PAGE_SIZE*MAX_ARG_PAGES); | 279 | len = strnlen_user((void __user *)p, MAX_ARG_STRLEN); |
270 | if (!len || len > PAGE_SIZE*MAX_ARG_PAGES) | 280 | if (!len || len > MAX_ARG_STRLEN) |
271 | return 0; | 281 | return 0; |
272 | p += len; | 282 | p += len; |
273 | } | 283 | } |
@@ -826,10 +836,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
826 | } | 836 | } |
827 | 837 | ||
828 | /* OK, This is the point of no return */ | 838 | /* OK, This is the point of no return */ |
829 | current->mm->start_data = 0; | ||
830 | current->mm->end_data = 0; | ||
831 | current->mm->end_code = 0; | ||
832 | current->mm->mmap = NULL; | ||
833 | current->flags &= ~PF_FORKNOEXEC; | 839 | current->flags &= ~PF_FORKNOEXEC; |
834 | current->mm->def_flags = def_flags; | 840 | current->mm->def_flags = def_flags; |
835 | 841 | ||
@@ -1051,9 +1057,13 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
1051 | 1057 | ||
1052 | compute_creds(bprm); | 1058 | compute_creds(bprm); |
1053 | current->flags &= ~PF_FORKNOEXEC; | 1059 | current->flags &= ~PF_FORKNOEXEC; |
1054 | create_elf_tables(bprm, &loc->elf_ex, | 1060 | retval = create_elf_tables(bprm, &loc->elf_ex, |
1055 | (interpreter_type == INTERPRETER_AOUT), | 1061 | (interpreter_type == INTERPRETER_AOUT), |
1056 | load_addr, interp_load_addr); | 1062 | load_addr, interp_load_addr); |
1063 | if (retval < 0) { | ||
1064 | send_sig(SIGKILL, current, 0); | ||
1065 | goto out; | ||
1066 | } | ||
1057 | /* N.B. passed_fileno might not be initialized? */ | 1067 | /* N.B. passed_fileno might not be initialized? */ |
1058 | if (interpreter_type == INTERPRETER_AOUT) | 1068 | if (interpreter_type == INTERPRETER_AOUT) |
1059 | current->mm->arg_start += strlen(passed_fileno) + 1; | 1069 | current->mm->arg_start += strlen(passed_fileno) + 1; |