diff -ur linux-2.6.9/fs/binfmt_elf.c linux-2.6.9.plasmaroo/fs/binfmt_elf.c --- linux-2.6.9/fs/binfmt_elf.c 2004-10-24 14:58:48.000000000 +0100 +++ linux-2.6.9.plasmaroo/fs/binfmt_elf.c 2004-11-19 20:11:36.000000000 +0000 @@ -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(); @@ -570,7 +576,8 @@ */ retval = -ENOMEM; - if (elf_ppnt->p_filesz > PATH_MAX) + if (elf_ppnt->p_filesz > PATH_MAX || + elf_ppnt->p_filesz == 0) goto out_free_file; elf_interpreter = (char *) kmalloc(elf_ppnt->p_filesz, GFP_KERNEL); @@ -580,8 +587,16 @@ 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 */ + retval = -EINVAL; + if (elf_interpreter[elf_ppnt->p_filesz - 1] != '\0') + goto out_free_interp; + /* If the program interpreter is one of these two, * then assume an iBCS2 image. Otherwise assume * a native linux image. @@ -616,8 +631,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 +794,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;