From a965b8f80388603d439ae2b8ee7b9b018a079f90 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Fri, 14 Jun 2013 16:43:17 +0100 Subject: 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". Difference in the 4.2 series, compared to unstable: * tools/libxc/xc_hvm_build_x86.c:setup_guest and xen/arch/arm/kernel.c:kernel_try_elf_prepare have different error handling in 4.2 to unstable; patch adjusted accordingly. This is part of the fix to a security issue, XSA-55. Signed-off-by: Ian Jackson xen-unstable version Reviewed-by: George Dunlap --- tools/libxc/xc_dom_elfloader.c | 25 +++++++++++++++++++++---- tools/libxc/xc_hvm_build_x86.c | 5 +++++ tools/xcutils/readnotes.c | 3 +++ 3 files changed, 29 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c index ea458864f0..4fb4da23a7 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,19 +319,23 @@ 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; + } if ( elf_xen_feature_get(XENFEAT_dom0, dom->parms.f_required) ) { xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: Kernel does not" " support unprivileged (DomU) operation", __FUNCTION__); - return -EINVAL; + rc = -EINVAL; + goto out; } /* find kernel segment */ @@ -338,7 +349,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_x86.c b/tools/libxc/xc_hvm_build_x86.c index ccfd8b5458..8165287a9a 100644 --- a/tools/libxc/xc_hvm_build_x86.c +++ b/tools/libxc/xc_hvm_build_x86.c @@ -403,11 +403,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 cfae99486c..d1f7a30f73 100644 --- a/tools/xcutils/readnotes.c +++ b/tools/xcutils/readnotes.c @@ -301,6 +301,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; } -- cgit v1.2.3