All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Anton D. Kachalov" <mouse@mayc.ru>
To: linux-kernel@vger.kernel.org
Subject: Re: [PATCH 1/2] binfmt_elf: FatELF support in the binary loader.
Date: Fri, 23 Oct 2009 13:49:14 +0400	[thread overview]
Message-ID: <4AE17C1A.4060009@mayc.ru> (raw)

[-- Attachment #1: Type: text/plain, Size: 237 bytes --]

I have made very similar patch but it's quite small and do not require
deep hacks.
It should works with "setarch" too to force selection of binary.
There is a tool to merge binaries. Glibc / binutils patch work in progress.

Rgds,
Anton

[-- Attachment #2: binfmt-truearch-mouse.patch --]
[-- Type: text/x-patch, Size: 3924 bytes --]

--- kernel-2.6.28-jaunty/fs/binfmt_elf.c.orig	2009-06-10 07:05:27.000000000 +0400
+++ kernel-2.6.28/fs/binfmt_elf.c	2009-09-29 14:46:39.008238197 +0400
@@ -571,6 +571,7 @@ static int load_elf_binary(struct linux_
 	unsigned long elf_bss, elf_brk;
 	int retval, i;
 	unsigned int size;
+	unsigned int offset;
 	unsigned long elf_entry;
 	unsigned long interp_load_addr = 0;
 	unsigned long start_code, end_code, start_data, end_data;
@@ -588,6 +589,8 @@ static int load_elf_binary(struct linux_
 		goto out_ret;
 	}
 	
+	offset = 0;
+retry_elf:
 	/* Get the exec-header */
 	loc->elf_ex = *((struct elfhdr *)bprm->buf);
 
@@ -598,8 +601,27 @@ static int load_elf_binary(struct linux_
 
 	if (loc->elf_ex.e_type != ET_EXEC && loc->elf_ex.e_type != ET_DYN)
 		goto out;
-	if (!elf_check_arch(&loc->elf_ex))
+#if (defined(__x86_64__) || defined(__powerpc64__) || defined(__s390x__)) \
+    && ELF_CLASS == ELFCLASS64
+	if (personality(current->personality) == PER_LINUX32)
 		goto out;
+#endif
+	if (!elf_check_arch(&loc->elf_ex)) {
+		offset = loc->elf_ex.e_ident[0xc]
+			| loc->elf_ex.e_ident[0xd] << 8
+			| loc->elf_ex.e_ident[0xe] << 16
+			| loc->elf_ex.e_ident[0xf] << 24;
+		if (offset != 0) {
+			memset(bprm->buf, 0, BINPRM_BUF_SIZE);
+			retval = kernel_read(bprm->file, offset, bprm->buf, BINPRM_BUF_SIZE);
+			if (retval != BINPRM_BUF_SIZE) {
+				retval = -ENOEXEC;
+				goto out;
+			}
+			goto retry_elf;
+		}
+		goto out;
+	}
 	if (!bprm->file->f_op||!bprm->file->f_op->mmap)
 		goto out;
 
@@ -723,13 +745,30 @@ static int load_elf_binary(struct linux_
 
 	/* Some simple consistency checks for the interpreter */
 	if (elf_interpreter) {
+		offset = 0;
+retry_interp:
 		retval = -ELIBBAD;
+		loc->interp_elf_ex = *((struct elfhdr *)bprm->buf);
 		/* Not an ELF interpreter */
 		if (memcmp(loc->interp_elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
 			goto out_free_dentry;
 		/* Verify the interpreter has a valid arch */
-		if (!elf_check_arch(&loc->interp_elf_ex))
+		if (!elf_check_arch(&loc->interp_elf_ex)) {
+			offset = loc->interp_elf_ex.e_ident[0xc]
+				| loc->interp_elf_ex.e_ident[0xd] << 8
+				| loc->interp_elf_ex.e_ident[0xe] << 16
+				| loc->interp_elf_ex.e_ident[0xf] << 24;
+			if (offset != 0) {
+				memset(bprm->buf, 0, BINPRM_BUF_SIZE);
+				retval = kernel_read(bprm->file, offset, bprm->buf, BINPRM_BUF_SIZE);
+				if (retval != BINPRM_BUF_SIZE) {
+					retval = -ELIBBAD;
+					goto out;
+				}
+				goto retry_interp;
+			}
 			goto out_free_dentry;
+		}
 	} else {
 		/* Executables without an interpreter also need a personality  */
 		SET_PERSONALITY(loc->elf_ex);
@@ -1026,18 +1065,42 @@ static int load_elf_library(struct file 
 	unsigned long elf_bss, bss, len;
 	int retval, error, i, j;
 	struct elfhdr elf_ex;
+	unsigned int offset;
 
 	error = -ENOEXEC;
 	retval = kernel_read(file, 0, (char *)&elf_ex, sizeof(elf_ex));
 	if (retval != sizeof(elf_ex))
 		goto out;
 
+	offset = 0;
+retry_lib:
 	if (memcmp(elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
 		goto out;
 
 	/* First of all, some simple consistency checks */
-	if (elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
-	    !elf_check_arch(&elf_ex) || !file->f_op || !file->f_op->mmap)
+	if (elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2)
+		goto out;
+#if (defined(__x86_64__) || defined(__powerpc64__) || defined(__s390x__)) \
+    && ELF_CLASS == ELFCLASS64
+	if (personality(current->personality) == PER_LINUX32)
+		goto out;
+#endif
+	if (!elf_check_arch(&elf_ex)) {
+		offset = elf_ex.e_ident[0xc]
+			| elf_ex.e_ident[0xd] << 8
+			| elf_ex.e_ident[0xe] << 16
+			| elf_ex.e_ident[0xf] << 24;
+		if (offset != 0) {
+			retval = kernel_read(file, offset, (char *)&elf_ex, sizeof(elf_ex));
+			if (retval != sizeof(elf_ex)) {
+				retval = -ENOEXEC;
+				goto out;
+			}
+			goto retry_lib;
+		}
+		goto out;
+	}
+	if (!file->f_op || !file->f_op->mmap)
 		goto out;
 
 	/* Now read in all of the header information */

             reply	other threads:[~2009-10-23 10:08 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-10-23  9:49 Anton D. Kachalov [this message]
2009-10-23 13:32 ` [PATCH 1/2] binfmt_elf: FatELF support in the binary loader Anton D. Kachalov
2009-10-24  0:20 ` Ryan C. Gordon
2009-10-24  9:00   ` Anton D. Kachalov
2009-10-24 18:14     ` Ryan C. Gordon
2009-10-26  6:03       ` Ryan C. Gordon
2009-10-30  2:22         ` Ryan C. Gordon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4AE17C1A.4060009@mayc.ru \
    --to=mouse@mayc.ru \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.