# This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/11/10 10:33:00-08:00 chrisw@osdl.org # [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: Chris Wright # Signed-off-by: Linus Torvalds # # fs/binfmt_elf.c # 2004/11/10 09:45:38-08:00 chrisw@osdl.org +24 -7 # binfmt_elf: handle partial reads gracefully # diff -Nru a/fs/binfmt_elf.c b/fs/binfmt_elf.c --- a/fs/binfmt_elf.c 2004-11-12 13:09:39 -08:00 +++ b/fs/binfmt_elf.c 2004-11-12 13:09:39 -08:00 @@ -335,9 +335,12 @@ 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; ie_phnum; i++, eppnt++) { @@ -532,8 +535,11 @@ 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 @@ 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 @@ 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 @@ } 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;