+ binfmt_elf-fix-checks-for-bad-address-fix.patch added to -mm tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch titled

     binfmt_elf: fix checks for bad address fix

has been added to the -mm tree.  Its filename is

     binfmt_elf-fix-checks-for-bad-address-fix.patch

See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find
out what to do about this

------------------------------------------------------
Subject: binfmt_elf: fix checks for bad address fix
From: Ernie Petrides <petrides@xxxxxxxxxx>


Hi, Chuck.  I did the RHEL3 and RHEL4 versions of those fixes, and I was
waiting for 2.6.17 to be released before testing and posting the changes
upstream (and I've been tied up this week and so hadn't gotten around to it
yet).

For background, the BAD_ADDR() macro should return TRUE if the address is
TASK_SIZE, because that's the lowest address that is *not* valid for
user-space mappings.  The macro was correct in binfmt_aout.c but was wrong
for the "equal to" case in binfmt_elf.c.  There were two in-line
validations of user-space addresses in binfmt_elf.c, which have been
appropriately converted to use the corrected BAD_ADDR() macro in the patch
you posted yesterday.  Note that the size checks against TASK_SIZE are okay
as coded.

The additional changes that I propose are below.  These are in the error
paths for bad ELF entry addresses once load_elf_binary() has already
committed to exec'ing the new image (following the tearing down of the
task's original address space).

The 1st hunk deals with the interp-side of the outer "if".  There were two
problems here.  The printk() should be removed because this path can be
triggered at will by a bogus interpreter image created and used by a
malicious user.  Further, the error code should not be ENOEXEC, because
that causes the loop in search_binary_handler() to continue trying other
exec handlers (twice, in fact).  But it's too late for this to work
correctly, because the user address space has already been torn down, and
an exec() failure cannot be returned to the user code because the code no
longer exists.  The only recovery is to force a SIGSEGV, but it's best to
terminate the search loop immediately.  I somewhat arbitrarily chose EINVAL
as a fallback error code, but any error returned by load_elf_interp() will
override that (but this value will never be seen by user-space).

The 2nd hunk deals with the non-interp-side of the outer "if".  There were
two problems here as well.  The SIGSEGV needs to be forced, because a prior
sigaction() syscall might have set the associated disposition to SIG_IGN. 
And the ENOEXEC should be changed to EINVAL as described above.

Signed-off-by: Ernie Petrides <petrides@xxxxxxxxxx>
Cc: Chuck Ebbert <76306.1226@xxxxxxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxx>
---

 fs/binfmt_elf.c |    9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff -puN fs/binfmt_elf.c~binfmt_elf-fix-checks-for-bad-address-fix fs/binfmt_elf.c
--- a/fs/binfmt_elf.c~binfmt_elf-fix-checks-for-bad-address-fix
+++ a/fs/binfmt_elf.c
@@ -941,10 +941,9 @@ static int load_elf_binary(struct linux_
 						    interpreter,
 						    &interp_load_addr);
 		if (BAD_ADDR(elf_entry)) {
-			printk(KERN_ERR "Unable to load interpreter %.128s\n",
-				elf_interpreter);
 			force_sig(SIGSEGV, current);
-			retval = -ENOEXEC; /* Nobody gets to see this, but.. */
+			retval = IS_ERR((void *)elf_entry) ?
+					(int)elf_entry : -EINVAL;
 			goto out_free_dentry;
 		}
 		reloc_func_desc = interp_load_addr;
@@ -955,8 +954,8 @@ static int load_elf_binary(struct linux_
 	} else {
 		elf_entry = loc->elf_ex.e_entry;
 		if (BAD_ADDR(elf_entry)) {
-			send_sig(SIGSEGV, current, 0);
-			retval = -ENOEXEC; /* Nobody gets to see this, but.. */
+			force_sig(SIGSEGV, current);
+			retval = -EINVAL;
 			goto out_free_dentry;
 		}
 	}
_

Patches currently in -mm which might be from petrides@xxxxxxxxxx are

binfmt_elf-fix-checks-for-bad-address.patch
binfmt_elf-fix-checks-for-bad-address-fix.patch

-
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Newbies FAQ]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Photo]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux