All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeremy Fitzhardinge <jeremy@goop.org>
To: "Ryan C. Gordon" <icculus@icculus.org>
Cc: linux-kernel@vger.kernel.org
Subject: Re: [RFC][PATCH 2/2] binfmt_elf: FatELF support for kernel modules.
Date: Tue, 20 Oct 2009 09:12:54 +0900	[thread overview]
Message-ID: <4ADD0086.9060304@goop.org> (raw)
In-Reply-To: <alpine.DEB.2.00.0910190422090.13303@andre.icculuslan>

On 10/19/09 23:41, Ryan C. Gordon wrote:
> Allows kernel modules to be FatELF binaries.
>
> Details, rationale, tools, and patches for handling FatELF binaries can be
> found at http://icculus.org/fatelf/
>
> Please note that this requires an updated depmod and modprobe to be truly
> effective, but an unmodified insmod can work with FatELF binaries.
>   

This seems much more dubious.  It would only encourage more binary
modules, which we're not very keen on doing.

    J

> Signed-off-by: Ryan C. Gordon <icculus@icculus.org>
> ---
>  kernel/module.c |   72 +++++++++++++++++++++++++++++++++++++++++++++++++++----
>  1 files changed, 67 insertions(+), 5 deletions(-)
>
> diff --git a/kernel/module.c b/kernel/module.c
> index 8b7d880..cda8f79 100644
> --- a/kernel/module.c
> +++ b/kernel/module.c
> @@ -2066,13 +2066,69 @@ static inline void kmemleak_load_module(struct module *mod, Elf_Ehdr *hdr,
>  }
>  #endif
>  
> +/*
> + * See if we're a valid FatELF binary, find the right record, and
> + *  return the offset of that record within the binary. Returns NULL if there's
> + *  a problem, or a pointer to the real ELF header if we're okay.
> + *  If we don't see the FatELF magic number, we assume this is a regular ELF
> + *  binary and let the regular ELF checks handle it.
> + *
> + * This is a simplified version of examine_fatelf in fs/binfmt_elf.c
> + */
> +static Elf_Ehdr *examine_fatelf_module(const unsigned char *hdr,
> +				       const unsigned long len)
> +{
> +	Elf_Ehdr elf;
> +	int records, i;
> +	const fatelf_hdr *fatelf = (const fatelf_hdr *) hdr;
> +
> +	if (likely(le32_to_cpu(fatelf->magic) != FATELF_MAGIC)) {
> +		return (Elf_Ehdr *) hdr;  /* not FatELF; not an error. */
> +	} else if (unlikely(le16_to_cpu(fatelf->version) != 1)) {
> +		return NULL; /* Unrecognized format version. */
> +	}
> +
> +	memset(&elf, 0, sizeof (elf));
> +
> +	records = (int) fatelf->num_records;  /* uint8, no byteswap needed */
> +	for (i = 0; i < records; i++) {
> +		const fatelf_record *record = &fatelf->records[i];
> +
> +		/* Fill in the data elf_check_arch() might care about. */
> +		elf.e_ident[EI_OSABI] = record->osabi;
> +		elf.e_ident[EI_CLASS] = record->word_size;
> +		elf.e_ident[EI_DATA] = record->byte_order;
> +		elf.e_machine = le16_to_cpu(record->machine);
> +
> +		if (likely(!elf_check_arch(&elf))) {
> +			continue;  /* Unsupported CPU architecture. */
> +		} else {
> +			const __u64 rec_offset = le64_to_cpu(record->offset);
> +			const __u64 rec_size = le64_to_cpu(record->size);
> +			const __u64 end_offset = rec_offset + rec_size;
> +			const unsigned long uloff = (unsigned long) rec_offset;
> +
> +			if (unlikely(end_offset < rec_offset)) {
> +				continue;  /* overflow (corrupt file?)... */
> +			} else if (unlikely(end_offset > len)) {
> +				continue;  /* past EOF. */
> +			}
> +
> +			return (Elf_Ehdr *) (hdr + uloff);
> +		}
> +	}
> +
> +	return NULL;  /* no binaries we could use. */
> +}
> +
>  /* Allocate and load the module: note that size of section 0 is always
>     zero, and we rely on this for optional sections. */
>  static noinline struct module *load_module(void __user *umod,
>  				  unsigned long len,
>  				  const char __user *uargs)
>  {
> -	Elf_Ehdr *hdr;
> +	Elf_Ehdr *hdr_alloc;  /* returned from vmalloc */
> +	Elf_Ehdr *hdr;  /* adjusted hdr_alloc for FatELF */
>  	Elf_Shdr *sechdrs;
>  	char *secstrings, *args, *modmagic, *strtab = NULL;
>  	char *staging;
> @@ -2094,14 +2150,20 @@ static noinline struct module *load_module(void __user *umod,
>  
>  	/* Suck in entire file: we'll want most of it. */
>  	/* vmalloc barfs on "unusual" numbers.  Check here */
> -	if (len > 64 * 1024 * 1024 || (hdr = vmalloc(len)) == NULL)
> +	if (len > 64 * 1024 * 1024 || (hdr_alloc = vmalloc(len)) == NULL)
>  		return ERR_PTR(-ENOMEM);
>  
> -	if (copy_from_user(hdr, umod, len) != 0) {
> +	if (copy_from_user(hdr_alloc, umod, len) != 0) {
>  		err = -EFAULT;
>  		goto free_hdr;
>  	}
>  
> +	hdr = examine_fatelf_module((unsigned char *) hdr_alloc, len);
> +	if (hdr == NULL) {
> +		err = -ENOEXEC;
> +		goto free_hdr;
> +	}
> +
>  	/* Sanity checks against insmoding binaries or wrong arch,
>             weird elf version */
>  	if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0
> @@ -2505,7 +2567,7 @@ static noinline struct module *load_module(void __user *umod,
>  	add_notes_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
>  
>  	/* Get rid of temporary copy */
> -	vfree(hdr);
> +	vfree(hdr_alloc);
>  
>  	trace_module_load(mod);
>  
> @@ -2538,7 +2600,7 @@ static noinline struct module *load_module(void __user *umod,
>  	kfree(args);
>  	kfree(strmap);
>   free_hdr:
> -	vfree(hdr);
> +	vfree(hdr_alloc);
>  	return ERR_PTR(err);
>  
>   truncated:
>   


  reply	other threads:[~2009-10-20  0:12 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-10-19 14:41 [RFC][PATCH 2/2] binfmt_elf: FatELF support for kernel modules Ryan C. Gordon
2009-10-20  0:12 ` Jeremy Fitzhardinge [this message]
2009-10-20  4:54   ` Ryan C. Gordon
2009-10-23 22:24     ` Jeremy Fitzhardinge
2009-10-24  0:31       ` Ryan C. Gordon
2009-10-24 11:14       ` Alan Cox
2009-10-26 19:14         ` Jeremy Fitzhardinge
2009-10-26 19:59           ` Alan Cox
2009-10-30  2:25           ` Ryan C. Gordon
2009-10-30 10:32             ` Alan Cox
2009-10-30 14:19               ` Ryan C. Gordon
2009-10-20  8:33 ` Américo Wang
2009-10-21  8:06   ` 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=4ADD0086.9060304@goop.org \
    --to=jeremy@goop.org \
    --cc=icculus@icculus.org \
    --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.