[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v1 3/4] XENVER_build_id: Provide ld-embedded build-ids
From: Martin Pohlack <mpohlack@xxxxxxxxx> 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 size is provided to the hypervisor). To make this work with libxc it requires expanding the hypercall to use a second parameter. We provide an 'raw' version of xc_version called xc_version_len. The wrapper around it is xc_version which retains the automatic size detection. 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. Suggested-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Signed-off-by: Martin Pohlack <mpohlack@xxxxxxxxx> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> --- tools/flask/policy/policy/modules/xen/xen.te | 1 + tools/libxc/include/xenctrl.h | 2 ++ tools/libxc/xc_private.c | 37 +++++++++++++++------------- tools/libxc/xc_private.h | 4 ++- xen/arch/x86/Makefile | 11 +++++---- xen/arch/x86/xen.lds.S | 6 +++++ xen/common/kernel.c | 32 +++++++++++++++++++++++- xen/common/version.c | 37 ++++++++++++++++++++++++++++ xen/include/public/version.h | 9 ++++++- xen/include/xen/version.h | 1 + xen/include/xsm/dummy.h | 1 + xen/xsm/flask/hooks.c | 3 +++ xen/xsm/flask/policy/access_vectors | 2 ++ 13 files changed, 121 insertions(+), 25 deletions(-) diff --git a/tools/flask/policy/policy/modules/xen/xen.te b/tools/flask/policy/policy/modules/xen/xen.te index d0ad758..98ba4f8 100644 --- a/tools/flask/policy/policy/modules/xen/xen.te +++ b/tools/flask/policy/policy/modules/xen/xen.te @@ -68,6 +68,7 @@ allow dom0_t xen_t:xen2 { resource_op psr_cmt_op psr_cat_op + version_priv }; allow dom0_t xen_t:xen2 { pmu_ctrl diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h index 3bfa00b..8e1c0c0 100644 --- a/tools/libxc/include/xenctrl.h +++ b/tools/libxc/include/xenctrl.h @@ -1633,6 +1633,8 @@ int xc_sysctl(xc_interface *xch, struct xen_sysctl *sysctl); int xc_version(xc_interface *xch, int cmd, void *arg); +int xc_version_len(xc_interface *xch, int cmd, void *arg, size_t len); + int xc_flask_op(xc_interface *xch, xen_flask_op_t *op); /* diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c index 7c39897..c12dc34 100644 --- a/tools/libxc/xc_private.c +++ b/tools/libxc/xc_private.c @@ -674,11 +674,28 @@ int xc_sysctl(xc_interface *xch, struct xen_sysctl *sysctl) return do_sysctl(xch, sysctl); } +int xc_version_len(xc_interface *xch, int cmd, void *arg, size_t len) +{ + DECLARE_HYPERCALL_BOUNCE(arg, len, XC_HYPERCALL_BUFFER_BOUNCE_OUT); + int rc; + + if ( (len != 0) && xc_hypercall_bounce_pre(xch, arg) ) + { + PERROR("Could not bounce buffer for version hypercall"); + return -ENOMEM; + } + + rc = do_xen_version(xch, cmd, HYPERCALL_BUFFER(arg), len); + + if ( len != 0 ) + xc_hypercall_bounce_post(xch, arg); + + return rc; +} + int xc_version(xc_interface *xch, int cmd, void *arg) { - DECLARE_HYPERCALL_BOUNCE(arg, 0, XC_HYPERCALL_BUFFER_BOUNCE_OUT); /* Size unknown until cmd decoded */ size_t sz; - int rc; switch ( cmd ) { @@ -716,21 +733,7 @@ int xc_version(xc_interface *xch, int cmd, void *arg) ERROR("xc_version: unknown command %d\n", cmd); return -EINVAL; } - - HYPERCALL_BOUNCE_SET_SIZE(arg, sz); - - if ( (sz != 0) && xc_hypercall_bounce_pre(xch, arg) ) - { - PERROR("Could not bounce buffer for version hypercall"); - return -ENOMEM; - } - - rc = do_xen_version(xch, cmd, HYPERCALL_BUFFER(arg)); - - if ( sz != 0 ) - xc_hypercall_bounce_post(xch, arg); - - return rc; + return xc_version_len(xch, cmd, arg, sz); } unsigned long xc_make_page_below_4G( diff --git a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h index 2df1d59..82ac1d4 100644 --- a/tools/libxc/xc_private.h +++ b/tools/libxc/xc_private.h @@ -227,7 +227,8 @@ void xc__hypercall_buffer_cache_release(xc_interface *xch); int do_xen_hypercall(xc_interface *xch, privcmd_hypercall_t *hypercall); -static inline int do_xen_version(xc_interface *xch, int cmd, xc_hypercall_buffer_t *dest) +static inline int do_xen_version(xc_interface *xch, int cmd, + xc_hypercall_buffer_t *dest, size_t len) { DECLARE_HYPERCALL; DECLARE_HYPERCALL_BUFFER_ARGUMENT(dest); @@ -235,6 +236,7 @@ static inline int do_xen_version(xc_interface *xch, int cmd, xc_hypercall_buffer hypercall.op = __HYPERVISOR_xen_version; hypercall.arg[0] = (unsigned long) cmd; hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(dest); + hypercall.arg[2] = len; return do_xen_hypercall(xch, &hypercall); } diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index 39a8059..7e4140a 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -108,12 +108,13 @@ $(TARGET)-syms: prelink.o xen.lds $(BASEDIR)/common/symbols-dummy.o $(BASEDIR)/common/symbols-dummy.o -o $(@D)/.$(@F).0 $(NM) -n $(@D)/.$(@F).0 | $(BASEDIR)/tools/symbols >$(@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) -n $(@D)/.$(@F).1 | $(BASEDIR)/tools/symbols >$(@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 $@ + $(OBJCOPY) --only-section=.note.gnu.build-id $@ build_id.o rm -f $(@D)/.$(@F).[0-9]* EFI_LDFLAGS = $(patsubst -m%,-mi386pep,$(LDFLAGS)) --subsystem=10 @@ -128,7 +129,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 &&) : @@ -141,8 +142,8 @@ $(TARGET).efi: prelink-efi.o efi.lds efi/relocs-dummy.o $(BASEDIR)/common/symbol $(guard) efi/mkreloc $(foreach base,$(VIRT_BASE) $(ALT_BASE),$(@D)/.$(@F).$(base).1) >$(@D)/.$(@F).1r.S $(guard) $(NM) -n $(@D)/.$(@F).$(VIRT_BASE).1 | $(guard) $(BASEDIR)/tools/symbols >$(@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 7bab8de..48df798 100644 --- a/xen/common/kernel.c +++ b/xen/common/kernel.c @@ -229,7 +229,8 @@ void __init do_initcalls(void) */ #define XENVER_CMD_XSM_CHECK ( (1U << XENVER_compile_info) | \ (1U << XENVER_changeset) | \ - (1U << XENVER_commandline) ) + (1U << XENVER_commandline) | \ + (1U << XENVER_build_id) ) DO(xen_version)(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg, unsigned int len) { @@ -367,6 +368,35 @@ DO(xen_version)(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg, if ( copy_to_guest(arg, saved_cmdline, ARRAY_SIZE(saved_cmdline)) ) return -EFAULT; return 0; + + case XENVER_build_id: + { + int rc; + char *p = NULL; + unsigned int sz = 0; + + if ( guest_handle_is_null(arg) ) + return -EINVAL; + + if ( len == 0 ) + return -EINVAL; + + if ( !guest_handle_okay(arg, len) ) + return -EINVAL; + + rc = xen_build_id(&p, &sz); + if ( rc ) + return rc; + + if ( sz > len ) + return -ENOMEM; + + if ( copy_to_guest(arg, p, sz) ) + return -EFAULT; + + return sz; + } + } return -ENOSYS; diff --git a/xen/common/version.c b/xen/common/version.c index b152e27..26eeadf 100644 --- a/xen/common/version.c +++ b/xen/common/version.c @@ -1,5 +1,9 @@ #include <xen/compile.h> #include <xen/version.h> +#include <xen/types.h> +#include <xen/string.h> +#include <xen/elf.h> +#include <xen/errno.h> const char *xen_compile_date(void) { @@ -55,3 +59,36 @@ const char *xen_banner(void) { return XEN_BANNER; } + +#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..e575d6b 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,12 @@ typedef struct xen_feature_info xen_feature_info_t; #define XENVER_commandline 9 typedef char xen_commandline_t[1024]; +#define XENVER_build_id 10 +/* + * arg1 == pointer to char array, arg2 == size of char array. + * Return value is the actual size. + */ + #endif /* __XEN_PUBLIC_VERSION_H__ */ /* diff --git a/xen/include/xen/version.h b/xen/include/xen/version.h index 81a3c7d..9584f36 100644 --- a/xen/include/xen/version.h +++ b/xen/include/xen/version.h @@ -12,5 +12,6 @@ unsigned int xen_minor_version(void); const char *xen_extra_version(void); const char *xen_changeset(void); const char *xen_banner(void); +int xen_build_id(char **p, unsigned int *len); #endif /* __XEN_VERSION_H__ */ diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index 2ee102e..66bc23e 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -729,6 +729,7 @@ static XSM_INLINE int xsm_version_op (XSM_DEFAULT_ARG uint32_t op) case XENVER_compile_info: case XENVER_changeset: case XENVER_commandline: + case XENVER_build_id: return xsm_default_action(XSM_PRIV, current->domain, NULL); case XENVER_version: case XENVER_extraversion: diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index 4f1269d..829aaeb 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -1631,6 +1631,9 @@ static int flask_version_op (uint32_t op) case XENVER_commandline: return current_has_perm(current->domain, SECCLASS_DOMAIN2, DOMAIN2__VERSION_USE); + case XENVER_build_id: + return avc_has_perm(domain_sid(current->domain), SECINITSID_XEN, + SECCLASS_XEN2, XEN2__VERSION_PRIV, NULL); case XENVER_version: case XENVER_extraversion: case XENVER_capabilities: diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors index 6e2e5d1..58b75a0 100644 --- a/xen/xsm/flask/policy/access_vectors +++ b/xen/xsm/flask/policy/access_vectors @@ -93,6 +93,8 @@ class xen2 pmu_ctrl # PMU use (domains, including unprivileged ones, will be using this operation) pmu_use +# XENVER_build_id and other priv + version_priv } # Classes domain and domain2 consist of operations that a domain performs on -- 2.1.0 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |