Messages in this thread Patch in this message | | | Date | Fri, 22 Oct 2004 20:54:42 -0700 | From | "Barry K. Nathan" <> | Subject | [PATCH][2.4] ELF fixes for executables with huge BSS (2/2) |
| |
This is a 2.4.27-2.4.28 port of this patch:
> [PATCH] binfmt_elf.c fix for 32-bit apps with large bss > > From: Julie DeWandel <jdewand@redhat.com> > > A problem exists where a 32-bit application can have a huge bss, one that > is so large that an overflow of the TASK_SIZE happens. But in this case, > the overflow is not detected in load_elf_binary(). Instead, because > arithmetic is being done using 32-bit containers, a truncation occurs and > the program gets loaded when it shouldn't have been. Subsequent execution > yields unpredictable results. > > The attached patch fixes this problem by checking for the overflow > condition and sending a SIGKILL to the application if the overflow is > detected. This problem can in theory exist when loading the elf > interpreter as well, so a similar check was added there.
Signed-off-by: Barry K. Nathan <barryn@pobox.com>
diff -ruN linux-2.4.28-pre4-bk2-bkn1/fs/binfmt_elf.c linux-2.4.28-pre4-bk2-bkn2/fs/binfmt_elf.c --- linux-2.4.28-pre4-bk2-bkn1/fs/binfmt_elf.c 2004-10-16 03:44:41.000000000 -0700 +++ linux-2.4.28-pre4-bk2-bkn2/fs/binfmt_elf.c 2004-10-16 04:16:38.000000000 -0700 @@ -332,6 +332,18 @@ } /* + * Check to see if the section's size will overflow the + * allowed task size. Note that p_filesz must always be + * <= p_memsize so it is only necessary to check p_memsz. + */ + k = load_addr + eppnt->p_vaddr; + if (k > TASK_SIZE || eppnt->p_filesz > eppnt->p_memsz || + eppnt->p_memsz > TASK_SIZE || TASK_SIZE - eppnt->p_memsz < k) { + error = -ENOMEM; + goto out_close; + } + + /* * Find the end of the file mapping for this phdr, and keep * track of the largest address we see for this. */ @@ -711,6 +723,19 @@ if (k < start_code) start_code = k; if (start_data < k) start_data = k; + /* + * Check to see if the section's size will overflow the + * allowed task size. Note that p_filesz must always be + * <= p_memsz so it is only necessary to check p_memsz. + */ + if (k > TASK_SIZE || elf_ppnt->p_filesz > elf_ppnt->p_memsz || + elf_ppnt->p_memsz > TASK_SIZE || + TASK_SIZE - elf_ppnt->p_memsz < k) { + /* set_brk can never work. Avoid overflows. */ + send_sig(SIGKILL, current, 0); + goto out_free_dentry; + } + k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz; if (k > elf_bss) - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |