From mboxrd@z Thu Jan 1 00:00:00 1970 From: Konrad Rzeszutek Wilk Subject: [PATCH v2 2/3] XENVER_build_id: Provide ld-embedded build-ids Date: Fri, 6 Nov 2015 14:36:16 -0500 Message-ID: <1446838577-7563-3-git-send-email-konrad.wilk@oracle.com> References: <1446838577-7563-1-git-send-email-konrad.wilk@oracle.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1ZumpE-000154-3n for xen-devel@lists.xenproject.org; Fri, 06 Nov 2015 19:37:28 +0000 In-Reply-To: <1446838577-7563-1-git-send-email-konrad.wilk@oracle.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: JBeulich@suse.com, mpohlack@amazon.de, andrew.cooper3@citrix.com, ian.campbell@citrix.com, wei.liu2@citrix.com, ian.jackson@eu.citrix.com, xen-devel@lists.xenproject.org, dgdegra@tycho.nsa.gov Cc: Konrad Rzeszutek Wilk List-Id: xen-devel@lists.xenproject.org From: Martin Pohlack The mechanism to get this is via the XENVER_build_id and we add a new subsequent sub-command to retrieve the binary build-id. The hypercall allows an arbitrary size (the buffer and len is provided to the hypervisor). Note that one can also retrieve the value by 'readelf -h xen-syms'. For EFI builds we re-use the same build-id that the xen-syms was built with. Note that there are no changes to the XSM files (dummy.c and hooks.c) as the priviliged subops fall in the default case. Since the new sub-ops provides the len parameter in the arguments to the hypercall we have to modify libxc to allow copying the arguments before the hypercall. We provide a new macro that modifies the bounce structure to change the direction. Suggested-by: Andrew Cooper Signed-off-by: Martin Pohlack Signed-off-by: Konrad Rzeszutek Wilk --- v1: Rebase it on Martin's initial patch v2: Move it to XENVER hypercall v3: Fix EFI building (Ross's fix) v4: Don't use the third argument for length. v5: Use new structure for XENVER_build_id with variable buf. --- tools/libxc/xc_private.c | 7 +++++++ tools/libxc/xc_private.h | 10 ++++++++++ xen/arch/x86/Makefile | 14 +++++++++----- xen/arch/x86/xen.lds.S | 6 ++++++ xen/common/kernel.c | 29 +++++++++++++++++++++++++++++ xen/common/version.c | 36 ++++++++++++++++++++++++++++++++++++ xen/include/public/version.h | 15 ++++++++++++++- xen/include/xen/version.h | 1 + xen/xsm/flask/policy/access_vectors | 2 +- 9 files changed, 113 insertions(+), 7 deletions(-) diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c index 7c39897..9cd676e 100644 --- a/tools/libxc/xc_private.c +++ b/tools/libxc/xc_private.c @@ -712,6 +712,13 @@ int xc_version(xc_interface *xch, int cmd, void *arg) case XENVER_commandline: sz = sizeof(xen_commandline_t); break; + case XENVER_build_id: + { + xen_build_id_t *build_id = (xen_build_id_t *)arg; + sz = sizeof(*build_id) + build_id->len; + HYPERCALL_BOUNCE_SET_DIR(arg, XC_HYPERCALL_BUFFER_BOUNCE_BOTH); + break; + } default: ERROR("xc_version: unknown command %d\n", cmd); return -EINVAL; diff --git a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h index 2df1d59..aa0cad7 100644 --- a/tools/libxc/xc_private.h +++ b/tools/libxc/xc_private.h @@ -202,6 +202,16 @@ enum { #define DECLARE_HYPERCALL_BOUNCE(_ubuf, _sz, _dir) DECLARE_NAMED_HYPERCALL_BOUNCE(_ubuf, _ubuf, _sz, _dir) /* + * Change the direction. + * + * Can only be used if the bounce_pre/bounce_post commands have + * not been used. + */ +#define HYPERCALL_BOUNCE_SET_DIR(_buf, _dir) do { if ((HYPERCALL_BUFFER(_buf))->hbuf) \ + assert(1); \ + (HYPERCALL_BUFFER(_buf))->dir = _dir; \ + } while (0) +/* * Set the size of data to bounce. Useful when the size is not known * when the bounce buffer is declared. */ diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index d4e507a..17a4830 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -109,15 +109,19 @@ $(TARGET)-syms: prelink.o xen.lds $(BASEDIR)/common/symbols-dummy.o $(NM) -pa --format=sysv $(@D)/.$(@F).0 \ | $(BASEDIR)/tools/symbols --sysv --sort >$(@D)/.$(@F).0.S $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).0.o - $(LD) $(LDFLAGS) -T xen.lds -N prelink.o \ + $(LD) $(LDFLAGS) -T xen.lds -N prelink.o --build-id=sha1 \ $(@D)/.$(@F).0.o -o $(@D)/.$(@F).1 $(NM) -pa --format=sysv $(@D)/.$(@F).1 \ | $(BASEDIR)/tools/symbols --sysv --sort --warn-dup >$(@D)/.$(@F).1.S $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).1.o - $(LD) $(LDFLAGS) -T xen.lds -N prelink.o \ + $(LD) $(LDFLAGS) -T xen.lds -N prelink.o --build-id=sha1 \ $(@D)/.$(@F).1.o -o $@ rm -f $(@D)/.$(@F).[0-9]* +build_id.o: $(TARGET)-syms + $(OBJCOPY) --only-section=.note.gnu.build-id $< build_id.o + + EFI_LDFLAGS = $(patsubst -m%,-mi386pep,$(LDFLAGS)) --subsystem=10 EFI_LDFLAGS += --image-base=$(1) --stack=0,0 --heap=0,0 --strip-debug EFI_LDFLAGS += --section-alignment=0x200000 --file-alignment=0x20 @@ -130,7 +134,7 @@ $(TARGET).efi: VIRT_BASE = 0x$(shell $(NM) efi/relocs-dummy.o | sed -n 's, A VIR $(TARGET).efi: ALT_BASE = 0x$(shell $(NM) efi/relocs-dummy.o | sed -n 's, A ALT_START$$,,p') # Don't use $(wildcard ...) here - at least make 3.80 expands this too early! $(TARGET).efi: guard = $(if $(shell echo efi/dis* | grep disabled),:) -$(TARGET).efi: prelink-efi.o efi.lds efi/relocs-dummy.o $(BASEDIR)/common/symbols-dummy.o efi/mkreloc +$(TARGET).efi: prelink-efi.o efi.lds efi/relocs-dummy.o $(BASEDIR)/common/symbols-dummy.o efi/mkreloc build_id.o $(foreach base, $(VIRT_BASE) $(ALT_BASE), \ $(guard) $(LD) $(call EFI_LDFLAGS,$(base)) -T efi.lds -N $< efi/relocs-dummy.o \ $(BASEDIR)/common/symbols-dummy.o -o $(@D)/.$(@F).$(base).0 &&) : @@ -145,8 +149,8 @@ $(TARGET).efi: prelink-efi.o efi.lds efi/relocs-dummy.o $(BASEDIR)/common/symbol $(guard) $(NM) -pa --format=sysv $(@D)/.$(@F).$(VIRT_BASE).1 \ | $(guard) $(BASEDIR)/tools/symbols --sysv --sort >$(@D)/.$(@F).1s.S $(guard) $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).1r.o $(@D)/.$(@F).1s.o - $(guard) $(LD) $(call EFI_LDFLAGS,$(VIRT_BASE)) -T efi.lds -N $< \ - $(@D)/.$(@F).1r.o $(@D)/.$(@F).1s.o -o $@ + $(guard) $(LD) $(call EFI_LDFLAGS,$(VIRT_BASE)) -T efi.lds --build-id=sha1 -N $< \ + $(@D)/.$(@F).1r.o $(@D)/.$(@F).1s.o build_id.o -o $@ if $(guard) false; then rm -f $@; echo 'EFI support disabled'; fi rm -f $(@D)/.$(@F).[0-9]* diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S index 6553cff..c4aabc3 100644 --- a/xen/arch/x86/xen.lds.S +++ b/xen/arch/x86/xen.lds.S @@ -67,6 +67,12 @@ SECTIONS *(.rodata.*) } :text + .note.gnu.build-id : { + __note_gnu_build_id_start = .; + *(.note.gnu.build-id) + __note_gnu_build_id_end = .; + } :text + . = ALIGN(SMP_CACHE_BYTES); .data.read_mostly : { /* Exception table */ diff --git a/xen/common/kernel.c b/xen/common/kernel.c index d51a3ed..1574c63 100644 --- a/xen/common/kernel.c +++ b/xen/common/kernel.c @@ -366,6 +366,35 @@ DO(xen_version)(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) return -EFAULT; return 0; } + case XENVER_build_id: + { + xen_build_id_t build_id; + unsigned int sz; + int rc = 0; + char *p = NULL; + + if ( deny ) + return -EPERM; + + if ( copy_from_guest(&build_id, arg, 1) ) + return -EFAULT; + + if ( build_id.len == 0 ) + return -EINVAL; + + rc = xen_build_id(&p, &sz); + if ( rc ) + return rc; + + if ( sz > build_id.len ) + return -ENOMEM; + + if ( copy_to_guest_offset(arg, offsetof(xen_build_id_t, buf), + deny ? xen_deny() : p, sz) ) + return -EFAULT; + + return sz; + } } return -ENOSYS; diff --git a/xen/common/version.c b/xen/common/version.c index 786be4e..d556c35 100644 --- a/xen/common/version.c +++ b/xen/common/version.c @@ -1,5 +1,9 @@ #include #include +#include +#include +#include +#include const char *xen_compile_date(void) { @@ -60,3 +64,35 @@ const char *xen_deny(void) { return ""; } +#ifdef CONFIG_ARM +int xen_build_id(char **p, unsigned int *len) +{ + return -ENODATA; +} +#else +#define NT_GNU_BUILD_ID 3 + +extern const Elf_Note __note_gnu_build_id_start; /* Defined in linker script. */ +extern const char __note_gnu_build_id_end[]; +int xen_build_id(char **p, unsigned int *len) +{ + const Elf_Note *n = &__note_gnu_build_id_start; + + /* Something is wrong. */ + if ( __note_gnu_build_id_end <= (char *)&__note_gnu_build_id_start ) + return -ENODATA; + + /* Check if we really have a build-id. */ + if ( NT_GNU_BUILD_ID != n->type ) + return -ENODATA; + + /* Sanity check, name should be "GNU" for ld-generated build-id. */ + if ( strncmp(ELFNOTE_NAME(n), "GNU", n->namesz) != 0 ) + return -ENODATA; + + *len = n->descsz; + *p = ELFNOTE_DESC(n); + + return 0; +} +#endif diff --git a/xen/include/public/version.h b/xen/include/public/version.h index 44f26b0..adae298 100644 --- a/xen/include/public/version.h +++ b/xen/include/public/version.h @@ -30,7 +30,8 @@ #include "xen.h" -/* NB. All ops return zero on success, except XENVER_{version,pagesize} */ +/* NB. All ops return zero on success, except + * XENVER_{version,pagesize, build_id} */ /* arg == NULL; returns major:minor (16:16). */ #define XENVER_version 0 @@ -83,6 +84,18 @@ typedef struct xen_feature_info xen_feature_info_t; #define XENVER_commandline 9 typedef char xen_commandline_t[1024]; +/* arg = xen_build_id_t. Returns size in bytes or XEN_Exx. */ +#define XENVER_build_id 10 +struct xen_build_id { + uint32_t len; /* IN: size of buf[]. */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + unsigned char buf[]; +#elif defined(__GNUC__) + unsigned char buf[1]; /* OUT: Variable length buffer with build_id. */ +#endif +}; +typedef struct xen_build_id xen_build_id_t; + #endif /* __XEN_PUBLIC_VERSION_H__ */ /* diff --git a/xen/include/xen/version.h b/xen/include/xen/version.h index 2015c0b..466c977 100644 --- a/xen/include/xen/version.h +++ b/xen/include/xen/version.h @@ -13,5 +13,6 @@ const char *xen_extra_version(void); const char *xen_changeset(void); const char *xen_banner(void); const char *xen_deny(void); +int xen_build_id(char **p, unsigned int *len); #endif /* __XEN_VERSION_H__ */ diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors index 273459f..35bdb42 100644 --- a/xen/xsm/flask/policy/access_vectors +++ b/xen/xsm/flask/policy/access_vectors @@ -93,7 +93,7 @@ class xen2 pmu_ctrl # PMU use (domains, including unprivileged ones, will be using this operation) pmu_use -# XENVER_[compile_info|changeset|commandline|extraversion] usage. +# XENVER_[compile_info|changeset|commandline|extraversion|buildid] usage. version_priv } -- 2.1.0