xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Ian Jackson <ian.jackson@eu.citrix.com>
To: xen-devel@lists.xensource.com
Cc: andrew.cooper3@citrix.com, mattjd@gmail.com,
	Ian Jackson <ian.jackson@eu.citrix.com>,
	security@xen.org
Subject: [PATCH 11/21] libelf: Make all callers call elf_check_broken
Date: Thu, 13 Jun 2013 19:21:47 +0100	[thread overview]
Message-ID: <1371147717-21343-12-git-send-email-ian.jackson@eu.citrix.com> (raw)
In-Reply-To: <1371147717-21343-1-git-send-email-ian.jackson@eu.citrix.com>

This arranges that if the new pointer reference error checking
tripped, we actually get a message about it.  In this patch these
messages do not change the actual return values from the various
functions: so pointer reference errors do not prevent loading.  This
is for fear that some existing kernels might cause the code to make
these wild references, which would then break, which is not a good
thing in a security patch.

In xen/arch/x86/domain_build.c we have to introduce an "out" label and
change all of the "return rc" beyond the relevant point into "goto
out".

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

Differences in 4.1 backport:
 * No xen/arch/arm.
 * There was less error handling in xen/arch/x86/domain_build.c
   so less need to change it.

Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxc/xc_dom_elfloader.c |   22 +++++++++++++++++++---
 tools/libxc/xc_hvm_build.c     |    5 +++++
 tools/xcutils/readnotes.c      |    3 +++
 xen/arch/x86/domain_build.c    |   23 ++++++++++++++++++-----
 4 files changed, 45 insertions(+), 8 deletions(-)

diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
index 945df7a..e733afd 100644
--- a/tools/libxc/xc_dom_elfloader.c
+++ b/tools/libxc/xc_dom_elfloader.c
@@ -276,6 +276,13 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
             elf_store_field(elf, shdr, e32.sh_name, 0);
     }
 
+    if ( elf_check_broken(&syms) )
+        DOMPRINTF("%s: symbols ELF broken: %s", __FUNCTION__,
+                  elf_check_broken(&syms));
+    if ( elf_check_broken(elf) )
+        DOMPRINTF("%s: ELF broken: %s", __FUNCTION__,
+                  elf_check_broken(elf));
+
     if ( tables == 0 )
     {
         DOMPRINTF("%s: no symbol table present", __FUNCTION__);
@@ -312,13 +319,16 @@ static int xc_dom_parse_elf_kernel(struct xc_dom_image *dom)
     {
         xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: ELF image"
                      " has no shstrtab", __FUNCTION__);
-        return -EINVAL;
+        rc = -EINVAL;
+        goto out;
     }
 
     /* parse binary and get xen meta info */
     elf_parse_binary(elf);
     if ( (rc = elf_xen_parse(elf, &dom->parms)) != 0 )
-        return rc;
+    {
+        goto out;
+    }
 
     /* find kernel segment */
     dom->kernel_seg.vstart = dom->parms.virt_kstart;
@@ -331,7 +341,13 @@ static int xc_dom_parse_elf_kernel(struct xc_dom_image *dom)
     DOMPRINTF("%s: %s: 0x%" PRIx64 " -> 0x%" PRIx64 "",
               __FUNCTION__, dom->guest_type,
               dom->kernel_seg.vstart, dom->kernel_seg.vend);
-    return 0;
+    rc = 0;
+out:
+    if ( elf_check_broken(elf) )
+        DOMPRINTF("%s: ELF broken: %s", __FUNCTION__,
+                  elf_check_broken(elf));
+
+    return rc;
 }
 
 static int xc_dom_load_elf_kernel(struct xc_dom_image *dom)
diff --git a/tools/libxc/xc_hvm_build.c b/tools/libxc/xc_hvm_build.c
index e3efca9..6c4e41e 100644
--- a/tools/libxc/xc_hvm_build.c
+++ b/tools/libxc/xc_hvm_build.c
@@ -393,11 +393,16 @@ static int setup_guest(xc_interface *xch,
         munmap(page0, PAGE_SIZE);
     }
 
+    if ( elf_check_broken(&elf) )
+        ERROR("HVM ELF broken: %s", elf_check_broken(&elf));
+
     free(page_array);
     return 0;
 
  error_out:
     free(page_array);
+    if ( elf_check_broken(&elf) )
+        ERROR("HVM ELF broken, failing: %s", elf_check_broken(&elf));
     return -1;
 }
 
diff --git a/tools/xcutils/readnotes.c b/tools/xcutils/readnotes.c
index d462f80..b940a36 100644
--- a/tools/xcutils/readnotes.c
+++ b/tools/xcutils/readnotes.c
@@ -224,6 +224,9 @@ int main(int argc, char **argv)
 		printf("__xen_guest: %s\n",
                        elf_strfmt(&elf, elf_section_start(&elf, shdr)));
 
+	if (elf_check_broken(&elf))
+		printf("warning: broken ELF: %s\n", elf_check_broken(&elf));
+
 	return 0;
 }
 
diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c
index 6467c36..49bb6a5 100644
--- a/xen/arch/x86/domain_build.c
+++ b/xen/arch/x86/domain_build.c
@@ -374,7 +374,7 @@ int __init construct_dom0(
 #endif
     elf_parse_binary(&elf);
     if ( (rc = elf_xen_parse(&elf, &parms)) != 0 )
-        return rc;
+        goto out;
 
     /* compatibility check */
     compatible = 0;
@@ -413,7 +413,8 @@ int __init construct_dom0(
     if ( !compatible )
     {
         printk("Mismatch between Xen and DOM0 kernel\n");
-        return -EINVAL;
+        rc = -EINVAL;
+        goto out;
     }
 
 #if defined(__x86_64__)
@@ -727,7 +728,8 @@ int __init construct_dom0(
          (v_end > HYPERVISOR_COMPAT_VIRT_START(d)) )
     {
         printk("DOM0 image overlaps with Xen private area.\n");
-        return -EINVAL;
+        rc = -EINVAL;
+        goto out;
     }
 
     if ( is_pv_32on64_domain(d) )
@@ -907,7 +909,8 @@ int __init construct_dom0(
         {
             write_ptbase(current);
             printk("Invalid HYPERCALL_PAGE field in ELF notes.\n");
-            return -1;
+            rc = -1;
+            goto out;
         }
         hypercall_page_initialise(
             d, (void *)(unsigned long)parms.virt_hypercall);
@@ -1254,9 +1257,19 @@ int __init construct_dom0(
 
     BUG_ON(rc != 0);
 
-    iommu_dom0_init(dom0);
+    if ( elf_check_broken(&elf) )
+        printk(" Xen warning: dom0 kernel broken ELF: %s\n",
+               elf_check_broken(&elf));
 
+    iommu_dom0_init(dom0);
     return 0;
+
+out:
+    if ( elf_check_broken(&elf) )
+        printk(" Xen dom0 kernel broken ELF: %s\n",
+               elf_check_broken(&elf));
+
+    return rc;
 }
 
 /*
-- 
1.7.2.5

  parent reply	other threads:[~2013-06-13 18:21 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-13 18:21 [PATCH v8 00/21] XSA55 libelf fixes for Xen 4.1 Ian Jackson
2013-06-13 18:21 ` [PATCH 01/21] libelf: abolish libelf-relocate.c Ian Jackson
2013-06-13 18:21 ` [PATCH 02/21] libxc: introduce xc_dom_seg_to_ptr_pages Ian Jackson
2013-06-13 18:21 ` [PATCH 03/21] libxc: Fix range checking in xc_dom_pfn_to_ptr etc Ian Jackson
2013-06-13 18:21 ` [PATCH 04/21] libelf: abolish elf_sval and elf_access_signed Ian Jackson
2013-06-13 18:21 ` [PATCH 05/21] libelf/xc_dom_load_elf_symtab: Do not use "syms" uninitialised Ian Jackson
2013-06-13 18:21 ` [PATCH 06/21] libelf: introduce macros for memory access and pointer handling Ian Jackson
2013-06-13 18:21 ` [PATCH 07/21] tools/xcutils/readnotes: adjust print_l1_mfn_valid_note Ian Jackson
2013-06-13 18:21 ` [PATCH 08/21] libelf: check nul-terminated strings properly Ian Jackson
2013-06-13 18:21 ` [PATCH 09/21] libelf: check all pointer accesses Ian Jackson
2013-06-13 18:21 ` [PATCH 10/21] libelf: Check pointer references in elf_is_elfbinary Ian Jackson
2013-06-13 18:21 ` Ian Jackson [this message]
2013-06-13 18:21 ` [PATCH 12/21] libelf: use C99 bool for booleans Ian Jackson
2013-06-13 18:21 ` [PATCH 13/21] libelf: use only unsigned integers Ian Jackson
2013-06-13 18:21 ` [PATCH 14/21] libxc: Introduce xc_bitops.h Ian Jackson
2013-06-13 18:21 ` [PATCH 15/21] libelf: check loops for running away Ian Jackson
2013-06-13 18:21 ` [PATCH 16/21] libelf: abolish obsolete macros Ian Jackson
2013-06-13 18:21 ` [PATCH 17/21] libxc: Add range checking to xc_dom_binloader Ian Jackson
2013-06-13 18:21 ` [PATCH 18/21] libxc: check failure of xc_dom_*_to_ptr, xc_map_foreign_range Ian Jackson
2013-06-13 18:21 ` [PATCH 19/21] libxc: check return values from malloc Ian Jackson
2013-06-13 18:21 ` [PATCH 20/21] libxc: range checks in xc_dom_p2m_host and _guest Ian Jackson
2013-06-13 18:21 ` [PATCH 21/21] libxc: check blob size before proceeding in xc_dom_check_gzip Ian Jackson
  -- strict thread matches above, loose matches on Subject: below --
2013-06-12 16:00 [PATCH RFC v7 00/22] XSA55 libelf fixes for Xen 4.1 Ian Jackson
2013-06-12 16:00 ` [PATCH 11/21] libelf: Make all callers call elf_check_broken Ian Jackson

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=1371147717-21343-12-git-send-email-ian.jackson@eu.citrix.com \
    --to=ian.jackson@eu.citrix.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=mattjd@gmail.com \
    --cc=security@xen.org \
    --cc=xen-devel@lists.xensource.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).