aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Jackson <ian.jackson@eu.citrix.com>2013-06-14 16:45:39 +0100
committerIan Jackson <Ian.Jackson@eu.citrix.com>2013-06-14 16:45:39 +0100
commit44c74b1ed31c75ed9026abf62ab7427a46d8027a (patch)
tree44af4b4eb8eb92b8686835f65012030beb97c8b5
parent9962d7ffcce97ec2d69a15ef861996b1ead33694 (diff)
downloadxen-44c74b1ed31c75ed9026abf62ab7427a46d8027a.tar.gz
xen-44c74b1ed31c75ed9026abf62ab7427a46d8027a.tar.bz2
xen-44c74b1ed31c75ed9026abf62ab7427a46d8027a.zip
libelf: Make all callers call elf_check_broken
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>
-rw-r--r--tools/libxc/xc_dom_elfloader.c22
-rw-r--r--tools/libxc/xc_hvm_build.c5
-rw-r--r--tools/xcutils/readnotes.c3
-rw-r--r--xen/arch/x86/domain_build.c23
4 files changed, 45 insertions, 8 deletions
diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
index 945df7a2aa..e733afd16e 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 e3efca98e8..6c4e41e5ea 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 d462f80245..b940a36722 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 6467c367b2..49bb6a5286 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;
}
/*