Index: oldkernel/linux/fs/binfmt_elf.c diff -u linux/fs/binfmt_elf.c:1.1.1.1 linux/fs/binfmt_elf.c:1.2 --- linux/fs/binfmt_elf.c:1.1.1.1 Wed May 31 12:33:48 2000 +++ linux/fs/binfmt_elf.c Thu Jun 1 15:33:31 2000 @@ -243,9 +243,10 @@ /* Now read in all of the header information */ - size = sizeof(struct elf_phdr) * interp_elf_ex->e_phnum; - if (size > ELF_EXEC_PAGESIZE) + if (interp_elf_ex->e_phnum < 1 || interp_elf_ex->e_phnum > + ELF_EXEC_PAGESIZE / sizeof(struct elf_phdr)) goto out; + size = sizeof(struct elf_phdr) * interp_elf_ex->e_phnum; elf_phdata = (struct elf_phdr *) kmalloc(size, GFP_KERNEL); if (!elf_phdata) goto out; @@ -333,6 +334,11 @@ MAP_FIXED|MAP_PRIVATE, 0); *interp_load_addr = load_addr; + /* + * AUDIT: is everything deallocated properly if this happens + * to be ~0UL? We'd better switch to out-of-band error reporting. + * Also for a.out. + */ error = ((unsigned long) interp_elf_ex->e_entry) + load_addr; out_close: @@ -447,10 +453,13 @@ /* Now read in all of the header information */ + if (elf_ex.e_phentsize != sizeof(struct elf_phdr) || + elf_ex.e_phnum < 1 || + elf_ex.e_phnum > 65536 / sizeof(struct elf_phdr)) + goto out; + retval = -ENOMEM; size = elf_ex.e_phentsize * elf_ex.e_phnum; - if (size > 65536) - goto out; elf_phdata = (struct elf_phdr *) kmalloc(size, GFP_KERNEL); if (!elf_phdata) goto out; @@ -476,8 +485,10 @@ for (i = 0; i < elf_ex.e_phnum; i++) { if (elf_ppnt->p_type == PT_INTERP) { - retval = -EINVAL; - if (elf_interpreter) + retval = -ENOEXEC; + if (elf_interpreter || + elf_ppnt->p_filesz < 2 || + elf_ppnt->p_filesz > PAGE_SIZE) goto out_free_interp; /* This is the program interpreter used for @@ -496,6 +507,7 @@ elf_ppnt->p_filesz, 1); if (retval < 0) goto out_free_interp; + elf_interpreter[elf_ppnt->p_filesz - 1] = 0; /* If the program interpreter is one of these two, * then assume an iBCS2 image. Otherwise assume * a native linux image. @@ -685,14 +697,17 @@ &interp_load_addr); dput(interpreter_dentry); - kfree(elf_interpreter); if (elf_entry == ~0UL) { - printk(KERN_ERR "Unable to load interpreter\n"); + printk(KERN_ERR "Unable to load interpreter %.128s\n", + elf_interpreter); + kfree(elf_interpreter); kfree(elf_phdata); send_sig(SIGSEGV, current, 0); return 0; } + + kfree(elf_interpreter); } kfree(elf_phdata);