diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/binfmt_elf.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index cea19a8ad438..9d16fc257332 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -335,9 +335,12 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex, goto out; retval = kernel_read(interpreter,interp_elf_ex->e_phoff,(char *)elf_phdata,size); - error = retval; - if (retval < 0) + error = -EIO; + if (retval != size) { + if (retval < 0) + error = retval; goto out_close; + } eppnt = elf_phdata; for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) { @@ -532,8 +535,11 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) goto out; retval = kernel_read(bprm->file, loc->elf_ex.e_phoff, (char *) elf_phdata, size); - if (retval < 0) + if (retval != size) { + if (retval >= 0) + retval = -EIO; goto out_free_ph; + } files = current->files; /* Refcounted so ok */ retval = unshare_files(); @@ -580,8 +586,14 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) retval = kernel_read(bprm->file, elf_ppnt->p_offset, elf_interpreter, elf_ppnt->p_filesz); - if (retval < 0) + if (retval != elf_ppnt->p_filesz) { + if (retval >= 0) + retval = -EIO; goto out_free_interp; + } + /* make sure path is NULL terminated */ + 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. @@ -616,8 +628,11 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) if (IS_ERR(interpreter)) goto out_free_interp; retval = kernel_read(interpreter, 0, bprm->buf, BINPRM_BUF_SIZE); - if (retval < 0) + if (retval != BINPRM_BUF_SIZE) { + if (retval >= 0) + retval = -EIO; goto out_free_dentry; + } /* Get the exec headers */ loc->interp_ex = *((struct exec *) bprm->buf); @@ -776,8 +791,10 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) } error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags); - if (BAD_ADDR(error)) - continue; + if (BAD_ADDR(error)) { + send_sig(SIGKILL, current, 0); + goto out_free_dentry; + } if (!load_addr_set) { load_addr_set = 1; |
