LWN.net Logo

binfmt_elf: handle partial reads gracefully

From:  Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
To:  bk-commits-head@vger.kernel.org
Subject:  [PATCH] binfmt_elf: handle partial reads gracefully
Date:  Wed, 10 Nov 2004 18:33:00 +0000

ChangeSet 1.2082, 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 <chrisw@osdl.org>
	Signed-off-by: Linus Torvalds <torvalds@osdl.org>



 binfmt_elf.c |   31 ++++++++++++++++++++++++-------
 1 files changed, 24 insertions(+), 7 deletions(-)


diff -Nru a/fs/binfmt_elf.c b/fs/binfmt_elf.c
--- a/fs/binfmt_elf.c	2004-11-10 11:05:15 -08:00
+++ b/fs/binfmt_elf.c	2004-11-10 11:05:15 -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; i<interp_elf_ex->e_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;
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Copyright © 2004, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds
Powered by Rackspace Managed Hosting.