[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v6 06/27] libelf-loader: introduce elf_load_image
Implement a new function, called elf_load_image, to perform the actually copy of the elf image and clearing the padding. The function is implemented as memcpy and memset when the library is built as part of the tools, but it is implemented as raw_copy_to_guest and raw_clear_guest when built as part of Xen, so that it can be safely called with an HVM style dom0. Changes in v5: - check the size of the arguments of elf_load_image. Changes in v4: - return a negative integer in case of errors in elf_load_image; propagate errors to elf_load_binary and further up the call chain. Changes in v3: - switch to raw_copy_to_guest and raw_clear_guest. Changes in v2: - remove CONFIG_KERNEL_NO_RELOC. Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx> Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxx> --- tools/libxc/xc_dom_elfloader.c | 8 +++++++- tools/libxc/xc_hvm_build.c | 5 +++-- xen/arch/x86/domain_build.c | 7 ++++++- xen/common/libelf/libelf-loader.c | 30 +++++++++++++++++++++++++++--- xen/include/xen/libelf.h | 2 +- 5 files changed, 44 insertions(+), 8 deletions(-) diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c index 4d7b8e0..2e69559 100644 --- a/tools/libxc/xc_dom_elfloader.c +++ b/tools/libxc/xc_dom_elfloader.c @@ -310,9 +310,15 @@ static int xc_dom_parse_elf_kernel(struct xc_dom_image *dom) static int xc_dom_load_elf_kernel(struct xc_dom_image *dom) { struct elf_binary *elf = dom->private_loader; + int rc; elf->dest = xc_dom_seg_to_ptr(dom, &dom->kernel_seg); - elf_load_binary(elf); + rc = elf_load_binary(elf); + if ( rc < 0 ) + { + DOMPRINTF("%s: failed to load elf binary", __FUNCTION__); + return rc; + } if ( dom->parms.bsd_symtab ) xc_dom_load_elf_symtab(dom, elf, 1); return 0; diff --git a/tools/libxc/xc_hvm_build.c b/tools/libxc/xc_hvm_build.c index 9831bab..1fa5658 100644 --- a/tools/libxc/xc_hvm_build.c +++ b/tools/libxc/xc_hvm_build.c @@ -109,8 +109,9 @@ static int loadelfimage( elf->dest += elf->pstart & (PAGE_SIZE - 1); /* Load the initial elf image. */ - elf_load_binary(elf); - rc = 0; + rc = elf_load_binary(elf); + if ( rc < 0 ) + PERROR("Failed to load elf binary\n"); munmap(elf->dest, pages << PAGE_SHIFT); elf->dest = NULL; diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c index 1b3818f..b3c5d4c 100644 --- a/xen/arch/x86/domain_build.c +++ b/xen/arch/x86/domain_build.c @@ -903,7 +903,12 @@ int __init construct_dom0( /* Copy the OS image and free temporary buffer. */ elf.dest = (void*)vkern_start; - elf_load_binary(&elf); + rc = elf_load_binary(&elf); + if ( rc < 0 ) + { + printk("Failed to load the kernel binary\n"); + return rc; + } bootstrap_map(NULL); if ( UNSET_ADDR != parms.virt_hypercall ) diff --git a/xen/common/libelf/libelf-loader.c b/xen/common/libelf/libelf-loader.c index 1ccf7d3..ab58b8b 100644 --- a/xen/common/libelf/libelf-loader.c +++ b/xen/common/libelf/libelf-loader.c @@ -107,11 +107,34 @@ void elf_set_log(struct elf_binary *elf, elf_log_callback *log_callback, elf->log_caller_data = log_caller_data; elf->verbose = verbose; } + +static int elf_load_image(void *dst, const void *src, uint64_t filesz, uint64_t memsz) +{ + memcpy(dst, src, filesz); + memset(dst + filesz, 0, memsz - filesz); + return 0; +} #else +#include <asm/guest_access.h> + void elf_set_verbose(struct elf_binary *elf) { elf->verbose = 1; } + +static int elf_load_image(void *dst, const void *src, uint64_t filesz, uint64_t memsz) +{ + int rc; + if ( filesz > ULONG_MAX || memsz > ULONG_MAX ) + return -1; + rc = raw_copy_to_guest(dst, src, filesz); + if ( rc != 0 ) + return -1; + rc = raw_clear_guest(dst + filesz, memsz - filesz); + if ( rc != 0 ) + return -1; + return 0; +} #endif /* Calculate the required additional kernel space for the elf image */ @@ -237,7 +260,7 @@ void elf_parse_binary(struct elf_binary *elf) __FUNCTION__, elf->pstart, elf->pend); } -void elf_load_binary(struct elf_binary *elf) +int elf_load_binary(struct elf_binary *elf) { const elf_phdr *phdr; uint64_t i, count, paddr, offset, filesz, memsz; @@ -256,11 +279,12 @@ void elf_load_binary(struct elf_binary *elf) dest = elf_get_ptr(elf, paddr); elf_msg(elf, "%s: phdr %" PRIu64 " at 0x%p -> 0x%p\n", __func__, i, dest, dest + filesz); - memcpy(dest, elf->image + offset, filesz); - memset(dest + filesz, 0, memsz - filesz); + if ( elf_load_image(dest, elf->image + offset, filesz, memsz) != 0 ) + return -1; } elf_load_bsdsyms(elf); + return 0; } void *elf_get_ptr(struct elf_binary *elf, unsigned long addr) diff --git a/xen/include/xen/libelf.h b/xen/include/xen/libelf.h index 9de84eb..d77bda6 100644 --- a/xen/include/xen/libelf.h +++ b/xen/include/xen/libelf.h @@ -198,7 +198,7 @@ void elf_set_log(struct elf_binary *elf, elf_log_callback*, #endif void elf_parse_binary(struct elf_binary *elf); -void elf_load_binary(struct elf_binary *elf); +int elf_load_binary(struct elf_binary *elf); void *elf_get_ptr(struct elf_binary *elf, unsigned long addr); uint64_t elf_lookup_addr(struct elf_binary *elf, const char *symbol); -- 1.7.2.5 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |