2.4.36-stable kernel tree
Revision | c2f7024f5fa4d8cf23aa24e0b4949ba67203acac (tree) |
---|---|
Zeit | 2006-08-27 20:26:01 |
Autor | Ernie Petrides <petrides@redh...> |
Commiter | Willy Tarreau |
[PATCH] binfmt_elf.c : fix checks for bad address
Fix check for bad address; use macro instead of open-coding two checks.
Explanation from Ernie Petries in 2.6 commit :
Note that this patch slightly differs from Ernie's in that the printk()
only got commented out instead of being removed, since a rate limited call
is expected soon.
@@ -77,7 +77,7 @@ static struct linux_binfmt elf_format = { | ||
77 | 77 | NULL, THIS_MODULE, load_elf_binary, load_elf_library, elf_core_dump, ELF_EXEC_PAGESIZE |
78 | 78 | }; |
79 | 79 | |
80 | -#define BAD_ADDR(x) ((unsigned long)(x) > TASK_SIZE) | |
80 | +#define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE) | |
81 | 81 | |
82 | 82 | static int set_brk(unsigned long start, unsigned long end) |
83 | 83 | { |
@@ -345,7 +345,7 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex, | ||
345 | 345 | * <= p_memsize so it is only necessary to check p_memsz. |
346 | 346 | */ |
347 | 347 | k = load_addr + eppnt->p_vaddr; |
348 | - if (k > TASK_SIZE || eppnt->p_filesz > eppnt->p_memsz || | |
348 | + if (BAD_ADDR(k) || eppnt->p_filesz > eppnt->p_memsz || | |
349 | 349 | eppnt->p_memsz > TASK_SIZE || TASK_SIZE - eppnt->p_memsz < k) { |
350 | 350 | error = -ENOMEM; |
351 | 351 | goto out_close; |
@@ -772,7 +772,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) | ||
772 | 772 | * allowed task size. Note that p_filesz must always be |
773 | 773 | * <= p_memsz so it is only necessary to check p_memsz. |
774 | 774 | */ |
775 | - if (k > TASK_SIZE || elf_ppnt->p_filesz > elf_ppnt->p_memsz || | |
775 | + if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz || | |
776 | 776 | elf_ppnt->p_memsz > TASK_SIZE || |
777 | 777 | TASK_SIZE - elf_ppnt->p_memsz < k) { |
778 | 778 | /* set_brk can never work. Avoid overflows. */ |
@@ -822,10 +822,13 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) | ||
822 | 822 | interpreter, |
823 | 823 | &interp_load_addr); |
824 | 824 | if (BAD_ADDR(elf_entry)) { |
825 | - printk(KERN_ERR "Unable to load interpreter %.128s\n", | |
826 | - elf_interpreter); | |
825 | + // FIXME - ratelimit this before re-enabling | |
826 | + // printk(KERN_ERR "Unable to load interpreter %.128s\n", | |
827 | + // elf_interpreter); | |
828 | + | |
827 | 829 | force_sig(SIGSEGV, current); |
828 | - retval = IS_ERR((void *)elf_entry) ? PTR_ERR((void *)elf_entry) : -ENOEXEC; | |
830 | + retval = IS_ERR((void *)elf_entry) ? | |
831 | + (int)elf_entry : -EINVAL; | |
829 | 832 | goto out_free_dentry; |
830 | 833 | } |
831 | 834 | reloc_func_desc = interp_load_addr; |
@@ -833,6 +836,12 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) | ||
833 | 836 | allow_write_access(interpreter); |
834 | 837 | fput(interpreter); |
835 | 838 | kfree(elf_interpreter); |
839 | + } else { | |
840 | + if (BAD_ADDR(elf_entry)) { | |
841 | + force_sig(SIGSEGV, current); | |
842 | + retval = -EINVAL; | |
843 | + goto out_free_dentry; | |
844 | + } | |
836 | 845 | } |
837 | 846 | |
838 | 847 | kfree(elf_phdata); |