diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/binfmt_elf.c | 15 |
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 | ||
89 | static int set_brk(unsigned long start, unsigned long end) | 89 | static 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 | } |