aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/binfmt_elf.c15
1 files changed, 7 insertions, 8 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index d0434406eaeb..f42e64210ee5 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -84,7 +84,7 @@ static struct linux_binfmt elf_format = {
84 .min_coredump = ELF_EXEC_PAGESIZE 84 .min_coredump = ELF_EXEC_PAGESIZE
85}; 85};
86 86
87#define BAD_ADDR(x) ((unsigned long)(x) > TASK_SIZE) 87#define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE)
88 88
89static int set_brk(unsigned long start, unsigned long end) 89static int set_brk(unsigned long start, unsigned long end)
90{ 90{
@@ -394,7 +394,7 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
394 * <= p_memsize so it's only necessary to check p_memsz. 394 * <= p_memsize so it's only necessary to check p_memsz.
395 */ 395 */
396 k = load_addr + eppnt->p_vaddr; 396 k = load_addr + eppnt->p_vaddr;
397 if (k > TASK_SIZE || 397 if (BAD_ADDR(k) ||
398 eppnt->p_filesz > eppnt->p_memsz || 398 eppnt->p_filesz > eppnt->p_memsz ||
399 eppnt->p_memsz > TASK_SIZE || 399 eppnt->p_memsz > TASK_SIZE ||
400 TASK_SIZE - eppnt->p_memsz < k) { 400 TASK_SIZE - eppnt->p_memsz < k) {
@@ -887,7 +887,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
887 * allowed task size. Note that p_filesz must always be 887 * allowed task size. Note that p_filesz must always be
888 * <= p_memsz so it is only necessary to check p_memsz. 888 * <= p_memsz so it is only necessary to check p_memsz.
889 */ 889 */
890 if (k > TASK_SIZE || elf_ppnt->p_filesz > elf_ppnt->p_memsz || 890 if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
891 elf_ppnt->p_memsz > TASK_SIZE || 891 elf_ppnt->p_memsz > TASK_SIZE ||
892 TASK_SIZE - elf_ppnt->p_memsz < k) { 892 TASK_SIZE - elf_ppnt->p_memsz < k) {
893 /* set_brk can never work. Avoid overflows. */ 893 /* set_brk can never work. Avoid overflows. */
@@ -941,10 +941,9 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
941 interpreter, 941 interpreter,
942 &interp_load_addr); 942 &interp_load_addr);
943 if (BAD_ADDR(elf_entry)) { 943 if (BAD_ADDR(elf_entry)) {
944 printk(KERN_ERR "Unable to load interpreter %.128s\n",
945 elf_interpreter);
946 force_sig(SIGSEGV, current); 944 force_sig(SIGSEGV, current);
947 retval = -ENOEXEC; /* Nobody gets to see this, but.. */ 945 retval = IS_ERR((void *)elf_entry) ?
946 (int)elf_entry : -EINVAL;
948 goto out_free_dentry; 947 goto out_free_dentry;
949 } 948 }
950 reloc_func_desc = interp_load_addr; 949 reloc_func_desc = interp_load_addr;
@@ -955,8 +954,8 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
955 } else { 954 } else {
956 elf_entry = loc->elf_ex.e_entry; 955 elf_entry = loc->elf_ex.e_entry;
957 if (BAD_ADDR(elf_entry)) { 956 if (BAD_ADDR(elf_entry)) {
958 send_sig(SIGSEGV, current, 0); 957 force_sig(SIGSEGV, current);
959 retval = -ENOEXEC; /* Nobody gets to see this, but.. */ 958 retval = -EINVAL;
960 goto out_free_dentry; 959 goto out_free_dentry;
961 } 960 }
962 } 961 }