]> xenbits.xensource.com Git - xen.git/commitdiff
libelf: Check pointer references in elf_is_elfbinary
authorIan Jackson <ian.jackson@eu.citrix.com>
Fri, 14 Jun 2013 15:45:38 +0000 (16:45 +0100)
committerIan Jackson <Ian.Jackson@eu.citrix.com>
Fri, 14 Jun 2013 15:45:38 +0000 (16:45 +0100)
elf_is_elfbinary didn't take a length parameter and could potentially
access out of range when provided with a very short image.

We only need to check the size is enough for the actual dereference in
elf_is_elfbinary; callers are just using it to check the magic number
and do their own checks (usually via the new elf_ptrval system) before
dereferencing other parts of the header.

This is part of the fix to a security issue, XSA-55.

Conflicts in 4.1 backport:
 * xen/arch/x86/bzimage.c in 4.1 doesn't use elf_is_elfbinary.

Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
tools/libxc/xc_dom_elfloader.c
xen/common/libelf/libelf-loader.c
xen/common/libelf/libelf-tools.c
xen/include/xen/libelf.h

index b10790a5371e3814720475737a36fb500d0c50e6..945df7a2aa06a01ebc5a9bb807275876a2168bc5 100644 (file)
@@ -95,7 +95,7 @@ static int check_elf_kernel(struct xc_dom_image *dom, int verbose)
         return -EINVAL;
     }
 
-    if ( !elf_is_elfbinary(dom->kernel_blob) )
+    if ( !elf_is_elfbinary(dom->kernel_blob, dom->kernel_size) )
     {
         if ( verbose )
             xc_dom_panic(dom->xch,
index 7bf5e331e334bba1a6ceffc0e8f91a07e8b1bb40..96b0fe52f0b4779afb18913e44394fa1b1c29715 100644 (file)
@@ -25,7 +25,7 @@ int elf_init(struct elf_binary *elf, const char *image_input, size_t size)
     ELF_HANDLE_DECL(elf_shdr) shdr;
     uint64_t i, count, section, offset;
 
-    if ( !elf_is_elfbinary(image_input) )
+    if ( !elf_is_elfbinary(image_input, size) )
     {
         elf_err(elf, "%s: not an ELF binary\n", __FUNCTION__);
         return -1;
index 4a893f7e7809fa03cf418cbc01b5b2c320030651..3419f0c7242e5976ca7e08a31ec18b9c056fb1aa 100644 (file)
@@ -311,11 +311,14 @@ ELF_HANDLE_DECL(elf_note) elf_note_next(struct elf_binary *elf, ELF_HANDLE_DECL(
 
 /* ------------------------------------------------------------------------ */
 
-int elf_is_elfbinary(const void *image)
+int elf_is_elfbinary(const void *image_start, size_t image_size)
 {
-    const Elf32_Ehdr *ehdr = image;
+    const Elf32_Ehdr *ehdr = image_start;
 
-    return IS_ELF(*ehdr); /* fixme unchecked */
+    if ( image_size < sizeof(*ehdr) )
+        return 0;
+
+    return IS_ELF(*ehdr);
 }
 
 int elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr)
index 827fcfd8f79a1515d7db269dd4a1f7c169bda534..8698f67cd2cbbd6f0062958506e12c4d41305d72 100644 (file)
@@ -350,7 +350,9 @@ ELF_PTRVAL_CONST_VOID elf_note_desc(struct elf_binary *elf, ELF_HANDLE_DECL(elf_
 uint64_t elf_note_numeric(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
 ELF_HANDLE_DECL(elf_note) elf_note_next(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
 
-int elf_is_elfbinary(const void *image);
+/* (Only) checks that the image has the right magic number. */
+int elf_is_elfbinary(const void *image_start, size_t image_size);
+
 int elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr);
 
 /* ------------------------------------------------------------------------ */