Commit ad49d6ba authored by Chris Wright's avatar Chris Wright Committed by Linus Torvalds

[PATCH] binfmt_elf: handle partial reads gracefully

Make sure kernel reads full size of elf data.  Error out if mmap fails
when mapping any sections of the executable.  Make sure interpreter
string is NULL terminated. 
Signed-off-by: default avatarChris Wright <chrisw@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent bea14a1c
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment