• R/O
  • HTTP
  • SSH
  • HTTPS

linux-2.4.36: コミット

2.4.36-stable kernel tree


コミットメタ情報

リビジョンc2f7024f5fa4d8cf23aa24e0b4949ba67203acac (tree)
日時2006-08-27 20:26:01
作者Ernie Petrides <petrides@redh...>
コミッター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 :

For background, the BAD_ADDR() macro should return TRUE if the address is
TASK_SIZE, because that's the lowest address that is *not* valid for
user-space mappings. The macro was correct in binfmt_aout.c but was wrong
for the "equal to" case in binfmt_elf.c. There were two in-line validations
of user-space addresses in binfmt_elf.c, which have been appropriately
converted to use the corrected BAD_ADDR() macro in the patch you posted
  1. Note that the size checks against TASK_SIZE are okay as coded.

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.

変更サマリ

差分

--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -77,7 +77,7 @@ static struct linux_binfmt elf_format = {
7777 NULL, THIS_MODULE, load_elf_binary, load_elf_library, elf_core_dump, ELF_EXEC_PAGESIZE
7878 };
7979
80-#define BAD_ADDR(x) ((unsigned long)(x) > TASK_SIZE)
80+#define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE)
8181
8282 static int set_brk(unsigned long start, unsigned long end)
8383 {
@@ -345,7 +345,7 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
345345 * <= p_memsize so it is only necessary to check p_memsz.
346346 */
347347 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 ||
349349 eppnt->p_memsz > TASK_SIZE || TASK_SIZE - eppnt->p_memsz < k) {
350350 error = -ENOMEM;
351351 goto out_close;
@@ -772,7 +772,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
772772 * allowed task size. Note that p_filesz must always be
773773 * <= p_memsz so it is only necessary to check p_memsz.
774774 */
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 ||
776776 elf_ppnt->p_memsz > TASK_SIZE ||
777777 TASK_SIZE - elf_ppnt->p_memsz < k) {
778778 /* set_brk can never work. Avoid overflows. */
@@ -822,10 +822,13 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
822822 interpreter,
823823 &interp_load_addr);
824824 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+
827829 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;
829832 goto out_free_dentry;
830833 }
831834 reloc_func_desc = interp_load_addr;
@@ -833,6 +836,12 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
833836 allow_write_access(interpreter);
834837 fput(interpreter);
835838 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+ }
836845 }
837846
838847 kfree(elf_phdata);
旧リポジトリブラウザで表示