Daniel De Graaf
2013-Jan-10 15:33 UTC
[PATCH v7 00/22] Merge IS_PRIV checks into XSM hooks
Changes from v6: * Remove patches the have been applied; rebase on xen-unstable * Reorder patches to fix header autogeneration first * Add documentation of the current XSM permissions Changes from v5: * Add a few comments/docs * Remove CPP hackery so ctags can find dummy XSM hook implementations * Clean up XSM hooks that are redundant after the introduction of the generic domctl, sysctl, and platform_hypercall sub-operation hooks. * Add a parameter of type enum xsm_default to XSM hook invocations to document the default action of an XSM hook at the call site. Changes from v4: * Removed patches that have been applied * Rename __do_xsm_op to do_xsm_op * Rebased on current xen-unstable * Policy headers moved under hypervisor Changes from v3: * Moved x86-specific sysctls inside #ifdef CONFIG_X86 * Removed pt_domain parameter from mmu_update hook when unused * Renamed xsm___do_xsm_op to xsm_do_xsm_op * Added struct domain* argument to arch_do_domctl * Cleaned up mem_event code duplication Changes from v2: * Added overall hooks for domctl, sysctl, and platform_hypercall so that new sub-operations are protected by IS_PRIV checks * Reorganized the IS_PRIV additions to dummy.h so they are added in the same patch that removes the IS_PRIV they are replacing * Reworked hooks in the MM hotpath to increase efficiency * Dropped some unneeded XSM hook additions due to do_domctl hook * Dropped the rcu_lock*target_domain_by_id function removal patch * Restore IS_PRIV check in PHYSDEVOP_alloc_irq_vector * Use the existing hook function structure for tmem Patch summary: Refactor XSM/FLASK compilation: [PATCH 01/22] xsm: Use the dummy XSM module if XSM is disabled [PATCH 02/22] flask: move policy headers into hypervisor Preparatory new XSM hooks: [PATCH 03/22] arch/x86: add distinct XSM hooks for map/unmap * the distinction here is required for pushing IS_PRIV into XSM IS_PRIV removal: [PATCH 04/22] xen: use XSM instead of IS_PRIV where duplicated [PATCH 05/22] xen: avoid calling rcu_lock_*target_domain when an XSM [PATCH 06/22] xen: convert do_domctl to use XSM [PATCH 07/22] xen: convert do_sysctl to use XSM [PATCH 08/22] arch/x86: convert platform_hypercall to use XSM Updates to FLASK allowing full emulation of IS_PRIV: [PATCH 09/22] xsm/flask: Add checks on the domain performing the [PATCH 10/22] xsm/flask: add missing hooks [PATCH 11/22] xsm/flask: add distinct SIDs for self/target access New or updated XSM hooks: [PATCH 12/22] arch/x86: Add missing mem_sharing XSM hooks [PATCH 13/22] arch/x86: use XSM hooks for get_pg_owner access checks [PATCH 14/22] xen: add XSM hook for XENMEM_exchange [PATCH 19/22] tmem: add XSM hooks [PATCH 20/22] xen/xsm: distinguish scheduler get/set operations Deletion of now-redundant XSM hooks: [PATCH 15/22] xen: domctl XSM hook removal [PATCH 16/22] xen: sysctl XSM hook removal [PATCH 17/22] xen: platform_hypercall XSM hook removal Documentation/readability improvements: [PATCH 18/22] xen/xsm: Add xsm_default parameter to XSM hooks [PATCH 21/22] xsm/flask: document the access vectors [PATCH 22/22] xsm/flask: remove unused permissions --- .gitignore | 5 + .hgignore | 5 + docs/misc/xsm-flask.txt | 43 +- tools/flask/policy/Makefile | 2 +- tools/flask/policy/policy/flask/Makefile | 41 - tools/flask/policy/policy/flask/access_vectors | 178 ---- tools/flask/policy/policy/modules/xen/xen.if | 72 +- tools/flask/policy/policy/modules/xen/xen.te | 25 +- xen/arch/x86/acpi/power.c | 2 +- xen/arch/x86/cpu/mcheck/mce.c | 5 +- xen/arch/x86/domctl.c | 94 +- xen/arch/x86/hvm/hvm.c | 64 +- xen/arch/x86/irq.c | 5 +- xen/arch/x86/mm.c | 92 +- xen/arch/x86/mm/mem_event.c | 41 +- xen/arch/x86/mm/mem_sharing.c | 25 +- xen/arch/x86/mm/paging.c | 2 +- xen/arch/x86/msi.c | 2 +- xen/arch/x86/physdev.c | 66 +- xen/arch/x86/platform_hypercall.c | 71 +- xen/arch/x86/sysctl.c | 17 +- xen/arch/x86/traps.c | 2 +- xen/common/domain.c | 17 +- xen/common/domctl.c | 101 +- xen/common/event_channel.c | 30 +- xen/common/grant_table.c | 71 +- xen/common/kexec.c | 5 +- xen/common/memory.c | 33 +- xen/common/schedule.c | 18 +- xen/common/sysctl.c | 57 +- xen/common/tmem.c | 3 + xen/common/xenoprof.c | 2 +- xen/drivers/char/console.c | 8 +- xen/drivers/passthrough/iommu.c | 10 +- xen/drivers/passthrough/pci.c | 4 +- xen/include/asm-x86/mem_event.h | 1 - xen/include/xen/sched.h | 6 + xen/include/xen/tmem_xen.h | 8 +- xen/include/xsm/dummy.h | 583 +++++++++++ xen/include/xsm/xsm.h | 633 ++++-------- xen/xsm/dummy.c | 673 +----------- xen/xsm/flask/Makefile | 25 + xen/xsm/flask/flask_op.c | 9 + xen/xsm/flask/hooks.c | 1080 +++++++++----------- xen/xsm/flask/include/av_perm_to_string.h | 135 --- xen/xsm/flask/include/av_permissions.h | 145 --- xen/xsm/flask/include/class_to_string.h | 15 - xen/xsm/flask/include/flask.h | 35 - xen/xsm/flask/include/initial_sid_to_string.h | 16 - xen/xsm/flask/include/objsec.h | 2 + xen/xsm/flask/policy/access_vectors | 436 ++++++++ .../flask => xen/xsm/flask/policy}/initial_sids | 0 .../xsm/flask/policy}/mkaccess_vector.sh | 4 +- .../flask => xen/xsm/flask/policy}/mkflask.sh | 6 +- .../xsm/flask/policy}/security_classes | 0 xen/xsm/xsm_core.c | 2 +- 56 files changed, 2212 insertions(+), 2820 deletions(-)
Daniel De Graaf
2013-Jan-10 15:33 UTC
[PATCH 01/22] xsm: Use the dummy XSM module if XSM is disabled
This patch moves the implementation of the dummy XSM module to a header file that provides inline functions when XSM_ENABLE is not defined. This reduces duplication between the dummy module and callers when the implementation of the dummy return is not just "return 0", and also provides better compile-time checking for completeness of the XSM implementations in the dummy module. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Cc: Jan Beulich <jbeulich@suse.com> Cc: Keir Fraser <keir@xen.org> --- xen/common/domctl.c | 2 - xen/include/xsm/dummy.h | 613 ++++++++++++++++++++++++++++++++++++++++++++++++ xen/include/xsm/xsm.h | 291 +++++++++++------------ xen/xsm/dummy.c | 607 +---------------------------------------------- xen/xsm/flask/hooks.c | 2 +- xen/xsm/xsm_core.c | 2 +- 6 files changed, 763 insertions(+), 754 deletions(-) create mode 100644 xen/include/xsm/dummy.h diff --git a/xen/common/domctl.c b/xen/common/domctl.c index ca789bb..05d9c55 100644 --- a/xen/common/domctl.c +++ b/xen/common/domctl.c @@ -279,10 +279,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) } break; } -#ifdef XSM_ENABLE case XEN_DOMCTL_getdomaininfo: break; -#endif default: if ( !IS_PRIV(current->domain) ) return -EPERM; diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h new file mode 100644 index 0000000..075572f --- /dev/null +++ b/xen/include/xsm/dummy.h @@ -0,0 +1,613 @@ +/* + * Default XSM hooks - IS_PRIV and IS_PRIV_FOR checks + * + * Author: Daniel De Graaf <dgdegra@tyhco.nsa.gov> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + */ + +#include <xen/sched.h> +#include <xsm/xsm.h> + +static XSM_INLINE void xsm_security_domaininfo(struct domain *d, + struct xen_domctl_getdomaininfo *info) +{ + return; +} + +static XSM_INLINE int xsm_setvcpucontext(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_pausedomain(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_unpausedomain(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_resumedomain(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_domain_create(struct domain *d, u32 ssidref) +{ + return 0; +} + +static XSM_INLINE int xsm_max_vcpus(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_destroydomain(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_vcpuaffinity(int cmd, struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_scheduler(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_getdomaininfo(struct domain *d) +{ + if ( !IS_PRIV(current->domain) ) + return -EPERM; + return 0; +} + +static XSM_INLINE int xsm_getvcpucontext(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_getvcpuinfo(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_domain_settime(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_set_target(struct domain *d, struct domain *e) +{ + return 0; +} + +static XSM_INLINE int xsm_domctl(struct domain *d, int cmd) +{ + return 0; +} + +static XSM_INLINE int xsm_set_virq_handler(struct domain *d, uint32_t virq) +{ + return 0; +} + +static XSM_INLINE int xsm_tbufcontrol(void) +{ + return 0; +} + +static XSM_INLINE int xsm_readconsole(uint32_t clear) +{ + return 0; +} + +static XSM_INLINE int xsm_sched_id(void) +{ + return 0; +} + +static XSM_INLINE int xsm_setdomainmaxmem(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_setdomainhandle(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_setdebugging(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_perfcontrol(void) +{ + return 0; +} + +static XSM_INLINE int xsm_debug_keys(void) +{ + return 0; +} + +static XSM_INLINE int xsm_getcpuinfo(void) +{ + return 0; +} + +static XSM_INLINE int xsm_get_pmstat(void) +{ + return 0; +} + +static XSM_INLINE int xsm_setpminfo(void) +{ + return 0; +} + +static XSM_INLINE int xsm_pm_op(void) +{ + return 0; +} + +static XSM_INLINE int xsm_do_mca(void) +{ + return 0; +} + +static XSM_INLINE int xsm_availheap(void) +{ + return 0; +} + +static XSM_INLINE int xsm_alloc_security_domain(struct domain *d) +{ + return 0; +} + +static XSM_INLINE void xsm_free_security_domain(struct domain *d) +{ + return; +} + +static XSM_INLINE int xsm_grant_mapref(struct domain *d1, struct domain *d2, + uint32_t flags) +{ + return 0; +} + +static XSM_INLINE int xsm_grant_unmapref(struct domain *d1, struct domain *d2) +{ + return 0; +} + +static XSM_INLINE int xsm_grant_setup(struct domain *d1, struct domain *d2) +{ + return 0; +} + +static XSM_INLINE int xsm_grant_transfer(struct domain *d1, struct domain *d2) +{ + return 0; +} + +static XSM_INLINE int xsm_grant_copy(struct domain *d1, struct domain *d2) +{ + return 0; +} + +static XSM_INLINE int xsm_grant_query_size(struct domain *d1, struct domain *d2) +{ + return 0; +} + +static XSM_INLINE int xsm_memory_adjust_reservation(struct domain *d1, + struct domain *d2) +{ + return 0; +} + +static XSM_INLINE int xsm_memory_stat_reservation(struct domain *d1, struct domain *d2) +{ + return 0; +} + +static XSM_INLINE int xsm_console_io(struct domain *d, int cmd) +{ + return 0; +} + +static XSM_INLINE int xsm_profile(struct domain *d, int op) +{ + return 0; +} + +static XSM_INLINE int xsm_kexec(void) +{ + return 0; +} + +static XSM_INLINE int xsm_schedop_shutdown(struct domain *d1, struct domain *d2) +{ + return 0; +} + +static XSM_INLINE int xsm_memory_pin_page(struct domain *d1, struct domain *d2, + struct page_info *page) +{ + return 0; +} + +static XSM_INLINE int xsm_evtchn_unbound(struct domain *d, struct evtchn *chn, + domid_t id2) +{ + return 0; +} + +static XSM_INLINE int xsm_evtchn_interdomain(struct domain *d1, struct evtchn + *chan1, struct domain *d2, struct evtchn *chan2) +{ + return 0; +} + +static XSM_INLINE void xsm_evtchn_close_post(struct evtchn *chn) +{ + return; +} + +static XSM_INLINE int xsm_evtchn_send(struct domain *d, struct evtchn *chn) +{ + return 0; +} + +static XSM_INLINE int xsm_evtchn_status(struct domain *d, struct evtchn *chn) +{ + return 0; +} + +static XSM_INLINE int xsm_evtchn_reset(struct domain *d1, struct domain *d2) +{ + return 0; +} + +static XSM_INLINE int xsm_alloc_security_evtchn(struct evtchn *chn) +{ + return 0; +} + +static XSM_INLINE void xsm_free_security_evtchn(struct evtchn *chn) +{ + return; +} + +static XSM_INLINE char *xsm_show_security_evtchn(struct domain *d, const struct evtchn *chn) +{ + return NULL; +} + +static XSM_INLINE int xsm_get_pod_target(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_set_pod_target(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_get_device_group(uint32_t machine_bdf) +{ + return 0; +} + +static XSM_INLINE int xsm_test_assign_device(uint32_t machine_bdf) +{ + return 0; +} + +static XSM_INLINE int xsm_assign_device(struct domain *d, uint32_t machine_bdf) +{ + return 0; +} + +static XSM_INLINE int xsm_deassign_device(struct domain *d, uint32_t machine_bdf) +{ + return 0; +} + +static XSM_INLINE int xsm_resource_plug_core(void) +{ + return 0; +} + +static XSM_INLINE int xsm_resource_unplug_core(void) +{ + return 0; +} + +static XSM_INLINE int xsm_resource_plug_pci(uint32_t machine_bdf) +{ + return 0; +} + +static XSM_INLINE int xsm_resource_unplug_pci(uint32_t machine_bdf) +{ + return 0; +} + +static XSM_INLINE int xsm_resource_setup_pci(uint32_t machine_bdf) +{ + return 0; +} + +static XSM_INLINE int xsm_resource_setup_gsi(int gsi) +{ + return 0; +} + +static XSM_INLINE int xsm_resource_setup_misc(void) +{ + return 0; +} + +static XSM_INLINE int xsm_page_offline(uint32_t cmd) +{ + return 0; +} + +static XSM_INLINE int xsm_lockprof(void) +{ + return 0; +} + +static XSM_INLINE int xsm_cpupool_op(void) +{ + return 0; +} + +static XSM_INLINE int xsm_sched_op(void) +{ + return 0; +} + +static XSM_INLINE long xsm_do_xsm_op(XEN_GUEST_HANDLE_PARAM(xsm_op_t) op) +{ + return -ENOSYS; +} + +static XSM_INLINE char *xsm_show_irq_sid(int irq) +{ + return NULL; +} + +static XSM_INLINE int xsm_map_domain_pirq(struct domain *d, int irq, void *data) +{ + return 0; +} + +static XSM_INLINE int xsm_irq_permission(struct domain *d, int pirq, uint8_t allow) +{ + return 0; +} + +static XSM_INLINE int xsm_iomem_permission(struct domain *d, uint64_t s, uint64_t e, uint8_t allow) +{ + return 0; +} + +static XSM_INLINE int xsm_pci_config_permission(struct domain *d, uint32_t machine_bdf, + uint16_t start, uint16_t end, + uint8_t access) +{ + return 0; +} + +#ifdef CONFIG_X86 +static XSM_INLINE int xsm_shadow_control(struct domain *d, uint32_t op) +{ + return 0; +} + +static XSM_INLINE int xsm_getpageframeinfo(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_getmemlist(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_hypercall_init(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_hvmcontext(struct domain *d, uint32_t cmd) +{ + return 0; +} + +static XSM_INLINE int xsm_address_size(struct domain *d, uint32_t cmd) +{ + return 0; +} + +static XSM_INLINE int xsm_machine_address_size(struct domain *d, uint32_t cmd) +{ + return 0; +} + +static XSM_INLINE int xsm_hvm_param(struct domain *d, unsigned long op) +{ + return 0; +} + +static XSM_INLINE int xsm_hvm_set_pci_intx_level(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_hvm_set_isa_irq_level(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_hvm_set_pci_link_route(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_hvm_inject_msi(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_mem_event(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_mem_sharing(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_apic(struct domain *d, int cmd) +{ + return 0; +} + +static XSM_INLINE int xsm_xen_settime(void) +{ + return 0; +} + +static XSM_INLINE int xsm_memtype(uint32_t access) +{ + return 0; +} + +static XSM_INLINE int xsm_microcode(void) +{ + return 0; +} + +static XSM_INLINE int xsm_physinfo(void) +{ + return 0; +} + +static XSM_INLINE int xsm_platform_quirk(uint32_t quirk) +{ + return 0; +} + +static XSM_INLINE int xsm_firmware_info(void) +{ + return 0; +} + +static XSM_INLINE int xsm_efi_call(void) +{ + return 0; +} + +static XSM_INLINE int xsm_acpi_sleep(void) +{ + return 0; +} + +static XSM_INLINE int xsm_change_freq(void) +{ + return 0; +} + +static XSM_INLINE int xsm_getidletime(void) +{ + return 0; +} + +static XSM_INLINE int xsm_machine_memory_map(void) +{ + return 0; +} + +static XSM_INLINE int xsm_domain_memory_map(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_mmu_normal_update(struct domain *d, struct domain *t, + struct domain *f, intpte_t fpte) +{ + return 0; +} + +static XSM_INLINE int xsm_mmu_machphys_update(struct domain *d, struct domain *f, + unsigned long mfn) +{ + return 0; +} + +static XSM_INLINE int xsm_update_va_mapping(struct domain *d, struct domain *f, + l1_pgentry_t pte) +{ + return 0; +} + +static XSM_INLINE int xsm_add_to_physmap(struct domain *d1, struct domain *d2) +{ + return 0; +} + +static XSM_INLINE int xsm_remove_from_physmap(struct domain *d1, struct domain *d2) +{ + return 0; +} + +static XSM_INLINE int xsm_sendtrigger(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_bind_pt_irq(struct domain *d, struct xen_domctl_bind_pt_irq *bind) +{ + return 0; +} + +static XSM_INLINE int xsm_unbind_pt_irq(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_pin_mem_cacheattr(struct domain *d) +{ + return 0; +} + +static XSM_INLINE int xsm_ext_vcpucontext(struct domain *d, uint32_t cmd) +{ + return 0; +} + +static XSM_INLINE int xsm_vcpuextstate(struct domain *d, uint32_t cmd) +{ + return 0; +} + +static XSM_INLINE int xsm_ioport_permission(struct domain *d, uint32_t s, uint32_t e, uint8_t allow) +{ + return 0; +} + +#endif diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index a949c1e..73169fe 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -21,12 +21,6 @@ typedef void xsm_op_t; DEFINE_XEN_GUEST_HANDLE(xsm_op_t); -#ifdef XSM_ENABLE - #define xsm_call(fn) xsm_ops->fn -#else - #define xsm_call(fn) 0 -#endif - /* policy magic number (defined by XSM_MAGIC) */ typedef u32 xsm_magic_t; #ifndef XSM_MAGIC @@ -139,7 +133,7 @@ struct xsm_operations { int (*cpupool_op)(void); int (*sched_op)(void); - long (*__do_xsm_op) (XEN_GUEST_HANDLE_PARAM(xsm_op_t) op); + long (*do_xsm_op) (XEN_GUEST_HANDLE_PARAM(xsm_op_t) op); #ifdef CONFIG_X86 int (*shadow_control) (struct domain *d, uint32_t op); @@ -184,629 +178,630 @@ struct xsm_operations { #endif }; -#endif - extern struct xsm_operations *xsm_ops; +#ifndef XSM_NO_WRAPPERS + static inline void xsm_security_domaininfo (struct domain *d, struct xen_domctl_getdomaininfo *info) { - (void)xsm_call(security_domaininfo(d, info)); + xsm_ops->security_domaininfo(d, info); } static inline int xsm_setvcpucontext(struct domain *d) { - return xsm_call(setvcpucontext(d)); + return xsm_ops->setvcpucontext(d); } static inline int xsm_pausedomain (struct domain *d) { - return xsm_call(pausedomain(d)); + return xsm_ops->pausedomain(d); } static inline int xsm_unpausedomain (struct domain *d) { - return xsm_call(unpausedomain(d)); + return xsm_ops->unpausedomain(d); } static inline int xsm_resumedomain (struct domain *d) { - return xsm_call(resumedomain(d)); + return xsm_ops->resumedomain(d); } static inline int xsm_domain_create (struct domain *d, u32 ssidref) { - return xsm_call(domain_create(d, ssidref)); + return xsm_ops->domain_create(d, ssidref); } static inline int xsm_max_vcpus(struct domain *d) { - return xsm_call(max_vcpus(d)); + return xsm_ops->max_vcpus(d); } static inline int xsm_destroydomain (struct domain *d) { - return xsm_call(destroydomain(d)); + return xsm_ops->destroydomain(d); } static inline int xsm_vcpuaffinity (int cmd, struct domain *d) { - return xsm_call(vcpuaffinity(cmd, d)); + return xsm_ops->vcpuaffinity(cmd, d); } static inline int xsm_scheduler (struct domain *d) { - return xsm_call(scheduler(d)); + return xsm_ops->scheduler(d); } static inline int xsm_getdomaininfo (struct domain *d) { - return xsm_call(getdomaininfo(d)); + return xsm_ops->getdomaininfo(d); } static inline int xsm_getvcpucontext (struct domain *d) { - return xsm_call(getvcpucontext(d)); + return xsm_ops->getvcpucontext(d); } static inline int xsm_getvcpuinfo (struct domain *d) { - return xsm_call(getvcpuinfo(d)); + return xsm_ops->getvcpuinfo(d); } static inline int xsm_domain_settime (struct domain *d) { - return xsm_call(domain_settime(d)); + return xsm_ops->domain_settime(d); } static inline int xsm_set_target (struct domain *d, struct domain *e) { - return xsm_call(set_target(d, e)); + return xsm_ops->set_target(d, e); } static inline int xsm_domctl (struct domain *d, int cmd) { - return xsm_call(domctl(d, cmd)); + return xsm_ops->domctl(d, cmd); } static inline int xsm_set_virq_handler (struct domain *d, uint32_t virq) { - return xsm_call(set_virq_handler(d, virq)); + return xsm_ops->set_virq_handler(d, virq); } static inline int xsm_tbufcontrol (void) { - return xsm_call(tbufcontrol()); + return xsm_ops->tbufcontrol(); } static inline int xsm_readconsole (uint32_t clear) { - return xsm_call(readconsole(clear)); + return xsm_ops->readconsole(clear); } static inline int xsm_sched_id (void) { - return xsm_call(sched_id()); + return xsm_ops->sched_id(); } static inline int xsm_setdomainmaxmem (struct domain *d) { - return xsm_call(setdomainmaxmem(d)); + return xsm_ops->setdomainmaxmem(d); } static inline int xsm_setdomainhandle (struct domain *d) { - return xsm_call(setdomainhandle(d)); + return xsm_ops->setdomainhandle(d); } static inline int xsm_setdebugging (struct domain *d) { - return xsm_call(setdebugging(d)); + return xsm_ops->setdebugging(d); } static inline int xsm_perfcontrol (void) { - return xsm_call(perfcontrol()); + return xsm_ops->perfcontrol(); } static inline int xsm_debug_keys (void) { - return xsm_call(debug_keys()); + return xsm_ops->debug_keys(); } static inline int xsm_availheap (void) { - return xsm_call(availheap()); + return xsm_ops->availheap(); } static inline int xsm_getcpuinfo (void) { - return xsm_call(getcpuinfo()); + return xsm_ops->getcpuinfo(); } static inline int xsm_get_pmstat(void) { - return xsm_call(get_pmstat()); + return xsm_ops->get_pmstat(); } static inline int xsm_setpminfo(void) { - return xsm_call(setpminfo()); + return xsm_ops->setpminfo(); } static inline int xsm_pm_op(void) { - return xsm_call(pm_op()); + return xsm_ops->pm_op(); } static inline int xsm_do_mca(void) { - return xsm_call(do_mca()); + return xsm_ops->do_mca(); } static inline int xsm_evtchn_unbound (struct domain *d1, struct evtchn *chn, domid_t id2) { - return xsm_call(evtchn_unbound(d1, chn, id2)); + return xsm_ops->evtchn_unbound(d1, chn, id2); } static inline int xsm_evtchn_interdomain (struct domain *d1, struct evtchn *chan1, struct domain *d2, struct evtchn *chan2) { - return xsm_call(evtchn_interdomain(d1, chan1, d2, chan2)); + return xsm_ops->evtchn_interdomain(d1, chan1, d2, chan2); } static inline void xsm_evtchn_close_post (struct evtchn *chn) { - (void)xsm_call(evtchn_close_post(chn)); + xsm_ops->evtchn_close_post(chn); } static inline int xsm_evtchn_send (struct domain *d, struct evtchn *chn) { - return xsm_call(evtchn_send(d, chn)); + return xsm_ops->evtchn_send(d, chn); } static inline int xsm_evtchn_status (struct domain *d, struct evtchn *chn) { - return xsm_call(evtchn_status(d, chn)); + return xsm_ops->evtchn_status(d, chn); } static inline int xsm_evtchn_reset (struct domain *d1, struct domain *d2) { - return xsm_call(evtchn_reset(d1, d2)); + return xsm_ops->evtchn_reset(d1, d2); } static inline int xsm_grant_mapref (struct domain *d1, struct domain *d2, uint32_t flags) { - return xsm_call(grant_mapref(d1, d2, flags)); + return xsm_ops->grant_mapref(d1, d2, flags); } static inline int xsm_grant_unmapref (struct domain *d1, struct domain *d2) { - return xsm_call(grant_unmapref(d1, d2)); + return xsm_ops->grant_unmapref(d1, d2); } static inline int xsm_grant_setup (struct domain *d1, struct domain *d2) { - return xsm_call(grant_setup(d1, d2)); + return xsm_ops->grant_setup(d1, d2); } static inline int xsm_grant_transfer (struct domain *d1, struct domain *d2) { - return xsm_call(grant_transfer(d1, d2)); + return xsm_ops->grant_transfer(d1, d2); } static inline int xsm_grant_copy (struct domain *d1, struct domain *d2) { - return xsm_call(grant_copy(d1, d2)); + return xsm_ops->grant_copy(d1, d2); } static inline int xsm_grant_query_size (struct domain *d1, struct domain *d2) { - return xsm_call(grant_query_size(d1, d2)); + return xsm_ops->grant_query_size(d1, d2); } static inline int xsm_alloc_security_domain (struct domain *d) { - return xsm_call(alloc_security_domain(d)); + return xsm_ops->alloc_security_domain(d); } static inline void xsm_free_security_domain (struct domain *d) { - (void)xsm_call(free_security_domain(d)); + xsm_ops->free_security_domain(d); } static inline int xsm_alloc_security_evtchn (struct evtchn *chn) { - return xsm_call(alloc_security_evtchn(chn)); + return xsm_ops->alloc_security_evtchn(chn); } static inline void xsm_free_security_evtchn (struct evtchn *chn) { - (void)xsm_call(free_security_evtchn(chn)); + (void)xsm_ops->free_security_evtchn(chn); } static inline char *xsm_show_security_evtchn (struct domain *d, const struct evtchn *chn) { - return xsm_call(show_security_evtchn(d, chn)); + return xsm_ops->show_security_evtchn(d, chn); } static inline int xsm_get_pod_target (struct domain *d) { - return xsm_call(get_pod_target(d)); + return xsm_ops->get_pod_target(d); } static inline int xsm_set_pod_target (struct domain *d) { - return xsm_call(set_pod_target(d)); + return xsm_ops->set_pod_target(d); } static inline int xsm_memory_adjust_reservation (struct domain *d1, struct domain *d2) { - return xsm_call(memory_adjust_reservation(d1, d2)); + return xsm_ops->memory_adjust_reservation(d1, d2); } static inline int xsm_memory_stat_reservation (struct domain *d1, struct domain *d2) { - return xsm_call(memory_stat_reservation(d1, d2)); + return xsm_ops->memory_stat_reservation(d1, d2); } static inline int xsm_memory_pin_page(struct domain *d1, struct domain *d2, struct page_info *page) { - return xsm_call(memory_pin_page(d1, d2, page)); + return xsm_ops->memory_pin_page(d1, d2, page); } static inline int xsm_remove_from_physmap(struct domain *d1, struct domain *d2) { - return xsm_call(remove_from_physmap(d1, d2)); + return xsm_ops->remove_from_physmap(d1, d2); } static inline int xsm_console_io (struct domain *d, int cmd) { - return xsm_call(console_io(d, cmd)); + return xsm_ops->console_io(d, cmd); } static inline int xsm_profile (struct domain *d, int op) { - return xsm_call(profile(d, op)); + return xsm_ops->profile(d, op); } static inline int xsm_kexec (void) { - return xsm_call(kexec()); + return xsm_ops->kexec(); } static inline int xsm_schedop_shutdown (struct domain *d1, struct domain *d2) { - return xsm_call(schedop_shutdown(d1, d2)); + return xsm_ops->schedop_shutdown(d1, d2); } static inline char *xsm_show_irq_sid (int irq) { - return xsm_call(show_irq_sid(irq)); + return xsm_ops->show_irq_sid(irq); } static inline int xsm_map_domain_pirq (struct domain *d, int irq, void *data) { - return xsm_call(map_domain_pirq(d, irq, data)); + return xsm_ops->map_domain_pirq(d, irq, data); } static inline int xsm_irq_permission (struct domain *d, int pirq, uint8_t allow) { - return xsm_call(irq_permission(d, pirq, allow)); + return xsm_ops->irq_permission(d, pirq, allow); } static inline int xsm_iomem_permission (struct domain *d, uint64_t s, uint64_t e, uint8_t allow) { - return xsm_call(iomem_permission(d, s, e, allow)); + return xsm_ops->iomem_permission(d, s, e, allow); } static inline int xsm_pci_config_permission (struct domain *d, uint32_t machine_bdf, uint16_t start, uint16_t end, uint8_t access) { - return xsm_call(pci_config_permission(d, machine_bdf, start, end, access)); + return xsm_ops->pci_config_permission(d, machine_bdf, start, end, access); } static inline int xsm_get_device_group(uint32_t machine_bdf) { - return xsm_call(get_device_group(machine_bdf)); + return xsm_ops->get_device_group(machine_bdf); } static inline int xsm_test_assign_device(uint32_t machine_bdf) { - return xsm_call(test_assign_device(machine_bdf)); + return xsm_ops->test_assign_device(machine_bdf); } static inline int xsm_assign_device(struct domain *d, uint32_t machine_bdf) { - return xsm_call(assign_device(d, machine_bdf)); + return xsm_ops->assign_device(d, machine_bdf); } static inline int xsm_deassign_device(struct domain *d, uint32_t machine_bdf) { - return xsm_call(deassign_device(d, machine_bdf)); + return xsm_ops->deassign_device(d, machine_bdf); } static inline int xsm_resource_plug_pci (uint32_t machine_bdf) { - return xsm_call(resource_plug_pci(machine_bdf)); + return xsm_ops->resource_plug_pci(machine_bdf); } static inline int xsm_resource_unplug_pci (uint32_t machine_bdf) { - return xsm_call(resource_unplug_pci(machine_bdf)); + return xsm_ops->resource_unplug_pci(machine_bdf); } static inline int xsm_resource_plug_core (void) { - return xsm_call(resource_plug_core()); + return xsm_ops->resource_plug_core(); } static inline int xsm_resource_unplug_core (void) { - return xsm_call(resource_unplug_core()); + return xsm_ops->resource_unplug_core(); } static inline int xsm_resource_setup_pci (uint32_t machine_bdf) { - return xsm_call(resource_setup_pci(machine_bdf)); + return xsm_ops->resource_setup_pci(machine_bdf); } static inline int xsm_resource_setup_gsi (int gsi) { - return xsm_call(resource_setup_gsi(gsi)); + return xsm_ops->resource_setup_gsi(gsi); } static inline int xsm_resource_setup_misc (void) { - return xsm_call(resource_setup_misc()); + return xsm_ops->resource_setup_misc(); } static inline int xsm_page_offline(uint32_t cmd) { - return xsm_call(page_offline(cmd)); + return xsm_ops->page_offline(cmd); } static inline int xsm_lockprof(void) { - return xsm_call(lockprof()); + return xsm_ops->lockprof(); } static inline int xsm_cpupool_op(void) { - return xsm_call(cpupool_op()); + return xsm_ops->cpupool_op(); } static inline int xsm_sched_op(void) { - return xsm_call(sched_op()); + return xsm_ops->sched_op(); } -static inline long __do_xsm_op (XEN_GUEST_HANDLE_PARAM(xsm_op_t) op) +static inline long xsm_do_xsm_op (XEN_GUEST_HANDLE_PARAM(xsm_op_t) op) { -#ifdef XSM_ENABLE - return xsm_ops->__do_xsm_op(op); -#else - return -ENOSYS; -#endif + return xsm_ops->do_xsm_op(op); } -#ifdef XSM_ENABLE -extern int xsm_init(unsigned long *module_map, const multiboot_info_t *mbi, - void *(*bootstrap_map)(const module_t *)); -extern int xsm_policy_init(unsigned long *module_map, - const multiboot_info_t *mbi, - void *(*bootstrap_map)(const module_t *)); -extern int register_xsm(struct xsm_operations *ops); -extern int unregister_xsm(struct xsm_operations *ops); -#else -static inline int xsm_init (unsigned long *module_map, - const multiboot_info_t *mbi, - void *(*bootstrap_map)(const module_t *)) -{ - return 0; -} -#endif - #ifdef CONFIG_X86 static inline int xsm_shadow_control (struct domain *d, uint32_t op) { - return xsm_call(shadow_control(d, op)); + return xsm_ops->shadow_control(d, op); } static inline int xsm_getpageframeinfo (struct domain *d) { - return xsm_call(getpageframeinfo(d)); + return xsm_ops->getpageframeinfo(d); } static inline int xsm_getmemlist (struct domain *d) { - return xsm_call(getmemlist(d)); + return xsm_ops->getmemlist(d); } static inline int xsm_hypercall_init (struct domain *d) { - return xsm_call(hypercall_init(d)); + return xsm_ops->hypercall_init(d); } static inline int xsm_hvmcontext (struct domain *d, uint32_t cmd) { - return xsm_call(hvmcontext(d, cmd)); + return xsm_ops->hvmcontext(d, cmd); } static inline int xsm_address_size (struct domain *d, uint32_t cmd) { - return xsm_call(address_size(d, cmd)); + return xsm_ops->address_size(d, cmd); } static inline int xsm_machine_address_size (struct domain *d, uint32_t cmd) { - return xsm_call(machine_address_size(d, cmd)); + return xsm_ops->machine_address_size(d, cmd); } static inline int xsm_hvm_param (struct domain *d, unsigned long op) { - return xsm_call(hvm_param(d, op)); + return xsm_ops->hvm_param(d, op); } static inline int xsm_hvm_set_pci_intx_level (struct domain *d) { - return xsm_call(hvm_set_pci_intx_level(d)); + return xsm_ops->hvm_set_pci_intx_level(d); } static inline int xsm_hvm_set_isa_irq_level (struct domain *d) { - return xsm_call(hvm_set_isa_irq_level(d)); + return xsm_ops->hvm_set_isa_irq_level(d); } static inline int xsm_hvm_set_pci_link_route (struct domain *d) { - return xsm_call(hvm_set_pci_link_route(d)); + return xsm_ops->hvm_set_pci_link_route(d); } static inline int xsm_hvm_inject_msi (struct domain *d) { - return xsm_call(hvm_inject_msi(d)); + return xsm_ops->hvm_inject_msi(d); } static inline int xsm_mem_event (struct domain *d) { - return xsm_call(mem_event(d)); + return xsm_ops->mem_event(d); } static inline int xsm_mem_sharing (struct domain *d) { - return xsm_call(mem_sharing(d)); + return xsm_ops->mem_sharing(d); } static inline int xsm_apic (struct domain *d, int cmd) { - return xsm_call(apic(d, cmd)); + return xsm_ops->apic(d, cmd); } static inline int xsm_xen_settime (void) { - return xsm_call(xen_settime()); + return xsm_ops->xen_settime(); } static inline int xsm_memtype (uint32_t access) { - return xsm_call(memtype(access)); + return xsm_ops->memtype(access); } static inline int xsm_microcode (void) { - return xsm_call(microcode()); + return xsm_ops->microcode(); } static inline int xsm_physinfo (void) { - return xsm_call(physinfo()); + return xsm_ops->physinfo(); } static inline int xsm_platform_quirk (uint32_t quirk) { - return xsm_call(platform_quirk(quirk)); + return xsm_ops->platform_quirk(quirk); } static inline int xsm_firmware_info (void) { - return xsm_call(firmware_info()); + return xsm_ops->firmware_info(); } static inline int xsm_efi_call (void) { - return xsm_call(efi_call()); + return xsm_ops->efi_call(); } static inline int xsm_acpi_sleep (void) { - return xsm_call(acpi_sleep()); + return xsm_ops->acpi_sleep(); } static inline int xsm_change_freq (void) { - return xsm_call(change_freq()); + return xsm_ops->change_freq(); } static inline int xsm_getidletime (void) { - return xsm_call(getidletime()); + return xsm_ops->getidletime(); } static inline int xsm_machine_memory_map(void) { - return xsm_call(machine_memory_map()); + return xsm_ops->machine_memory_map(); } static inline int xsm_domain_memory_map(struct domain *d) { - return xsm_call(domain_memory_map(d)); + return xsm_ops->domain_memory_map(d); } static inline int xsm_mmu_normal_update (struct domain *d, struct domain *t, struct domain *f, intpte_t fpte) { - return xsm_call(mmu_normal_update(d, t, f, fpte)); + return xsm_ops->mmu_normal_update(d, t, f, fpte); } static inline int xsm_mmu_machphys_update (struct domain *d1, struct domain *d2, unsigned long mfn) { - return xsm_call(mmu_machphys_update(d1, d2, mfn)); + return xsm_ops->mmu_machphys_update(d1, d2, mfn); } static inline int xsm_update_va_mapping(struct domain *d, struct domain *f, l1_pgentry_t pte) { - return xsm_call(update_va_mapping(d, f, pte)); + return xsm_ops->update_va_mapping(d, f, pte); } static inline int xsm_add_to_physmap(struct domain *d1, struct domain *d2) { - return xsm_call(add_to_physmap(d1, d2)); + return xsm_ops->add_to_physmap(d1, d2); } static inline int xsm_sendtrigger(struct domain *d) { - return xsm_call(sendtrigger(d)); + return xsm_ops->sendtrigger(d); } static inline int xsm_bind_pt_irq(struct domain *d, struct xen_domctl_bind_pt_irq *bind) { - return xsm_call(bind_pt_irq(d, bind)); + return xsm_ops->bind_pt_irq(d, bind); } static inline int xsm_unbind_pt_irq(struct domain *d) { - return xsm_call(unbind_pt_irq(d)); + return xsm_ops->unbind_pt_irq(d); } static inline int xsm_pin_mem_cacheattr(struct domain *d) { - return xsm_call(pin_mem_cacheattr(d)); + return xsm_ops->pin_mem_cacheattr(d); } static inline int xsm_ext_vcpucontext(struct domain *d, uint32_t cmd) { - return xsm_call(ext_vcpucontext(d, cmd)); + return xsm_ops->ext_vcpucontext(d, cmd); } static inline int xsm_vcpuextstate(struct domain *d, uint32_t cmd) { - return xsm_call(vcpuextstate(d, cmd)); + return xsm_ops->vcpuextstate(d, cmd); } static inline int xsm_ioport_permission (struct domain *d, uint32_t s, uint32_t e, uint8_t allow) { - return xsm_call(ioport_permission(d, s, e, allow)); + return xsm_ops->ioport_permission(d, s, e, allow); } #endif /* CONFIG_X86 */ +#endif /* XSM_NO_WRAPPERS */ + +extern int xsm_init(unsigned long *module_map, const multiboot_info_t *mbi, + void *(*bootstrap_map)(const module_t *)); +extern int xsm_policy_init(unsigned long *module_map, + const multiboot_info_t *mbi, + void *(*bootstrap_map)(const module_t *)); +extern int register_xsm(struct xsm_operations *ops); +extern int unregister_xsm(struct xsm_operations *ops); extern struct xsm_operations dummy_xsm_ops; extern void xsm_fixup_ops(struct xsm_operations *ops); +#else /* XSM_ENABLE */ + +#define XSM_INLINE inline +#include <xsm/dummy.h> + +static inline int xsm_init (unsigned long *module_map, + const multiboot_info_t *mbi, + void *(*bootstrap_map)(const module_t *)) +{ + return 0; +} +#endif /* XSM_ENABLE */ + #endif /* __XSM_H */ diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c index b726eaf..a2ce733 100644 --- a/xen/xsm/dummy.c +++ b/xen/xsm/dummy.c @@ -10,606 +10,9 @@ * as published by the Free Software Foundation. */ -#include <xen/sched.h> -#include <xsm/xsm.h> - -static void dummy_security_domaininfo(struct domain *d, - struct xen_domctl_getdomaininfo *info) -{ - return; -} - -static int dummy_setvcpucontext(struct domain *d) -{ - return 0; -} - -static int dummy_pausedomain (struct domain *d) -{ - return 0; -} - -static int dummy_unpausedomain (struct domain *d) -{ - return 0; -} - -static int dummy_resumedomain (struct domain *d) -{ - return 0; -} - -static int dummy_domain_create(struct domain *d, u32 ssidref) -{ - return 0; -} - -static int dummy_max_vcpus(struct domain *d) -{ - return 0; -} - -static int dummy_destroydomain (struct domain *d) -{ - return 0; -} - -static int dummy_vcpuaffinity (int cmd, struct domain *d) -{ - return 0; -} - -static int dummy_scheduler (struct domain *d) -{ - return 0; -} - -static int dummy_getdomaininfo (struct domain *d) -{ - if ( !IS_PRIV(current->domain) ) - return -EPERM; - return 0; -} - -static int dummy_getvcpucontext (struct domain *d) -{ - return 0; -} - -static int dummy_getvcpuinfo (struct domain *d) -{ - return 0; -} - -static int dummy_domain_settime (struct domain *d) -{ - return 0; -} - -static int dummy_set_target (struct domain *d, struct domain *e) -{ - return 0; -} - -static int dummy_domctl(struct domain *d, int cmd) -{ - return 0; -} - -static int dummy_set_virq_handler(struct domain *d, uint32_t virq) -{ - return 0; -} - -static int dummy_tbufcontrol (void) -{ - return 0; -} - -static int dummy_readconsole (uint32_t clear) -{ - return 0; -} - -static int dummy_sched_id (void) -{ - return 0; -} - -static int dummy_setdomainmaxmem (struct domain *d) -{ - return 0; -} - -static int dummy_setdomainhandle (struct domain *d) -{ - return 0; -} - -static int dummy_setdebugging (struct domain *d) -{ - return 0; -} - -static int dummy_perfcontrol (void) -{ - return 0; -} - -static int dummy_debug_keys (void) -{ - return 0; -} - -static int dummy_getcpuinfo (void) -{ - return 0; -} - -static int dummy_get_pmstat (void) -{ - return 0; -} - -static int dummy_setpminfo (void) -{ - return 0; -} - -static int dummy_pm_op (void) -{ - return 0; -} - -static int dummy_do_mca (void) -{ - return 0; -} - -static int dummy_availheap (void) -{ - return 0; -} - -static int dummy_alloc_security_domain (struct domain *d) -{ - return 0; -} - -static void dummy_free_security_domain (struct domain *d) -{ - return; -} - -static int dummy_grant_mapref (struct domain *d1, struct domain *d2, - uint32_t flags) -{ - return 0; -} - -static int dummy_grant_unmapref (struct domain *d1, struct domain *d2) -{ - return 0; -} - -static int dummy_grant_setup (struct domain *d1, struct domain *d2) -{ - return 0; -} - -static int dummy_grant_transfer (struct domain *d1, struct domain *d2) -{ - return 0; -} - -static int dummy_grant_copy (struct domain *d1, struct domain *d2) -{ - return 0; -} - -static int dummy_grant_query_size (struct domain *d1, struct domain *d2) -{ - return 0; -} - -static int dummy_memory_adjust_reservation (struct domain *d1, - struct domain *d2) -{ - return 0; -} - -static int dummy_memory_stat_reservation (struct domain *d1, struct domain *d2) -{ - return 0; -} - -static int dummy_console_io (struct domain *d, int cmd) -{ - return 0; -} - -static int dummy_profile (struct domain *d, int op) -{ - return 0; -} - -static int dummy_kexec (void) -{ - return 0; -} - -static int dummy_schedop_shutdown (struct domain *d1, struct domain *d2) -{ - return 0; -} - -static int dummy_memory_pin_page(struct domain *d1, struct domain *d2, struct page_info *page) -{ - return 0; -} - -static int dummy_evtchn_unbound (struct domain *d, struct evtchn *chn, - domid_t id2) -{ - return 0; -} - -static int dummy_evtchn_interdomain (struct domain *d1, struct evtchn - *chan1, struct domain *d2, struct evtchn *chan2) -{ - return 0; -} - -static void dummy_evtchn_close_post (struct evtchn *chn) -{ - return; -} - -static int dummy_evtchn_send (struct domain *d, struct evtchn *chn) -{ - return 0; -} - -static int dummy_evtchn_status (struct domain *d, struct evtchn *chn) -{ - return 0; -} - -static int dummy_evtchn_reset (struct domain *d1, struct domain *d2) -{ - return 0; -} - -static int dummy_alloc_security_evtchn (struct evtchn *chn) -{ - return 0; -} - -static void dummy_free_security_evtchn (struct evtchn *chn) -{ - return; -} - -static char *dummy_show_security_evtchn (struct domain *d, const struct evtchn *chn) -{ - return NULL; -} - -static int dummy_get_pod_target(struct domain *d) -{ - return 0; -} - -static int dummy_set_pod_target(struct domain *d) -{ - return 0; -} - -static int dummy_get_device_group (uint32_t machine_bdf) -{ - return 0; -} - -static int dummy_test_assign_device (uint32_t machine_bdf) -{ - return 0; -} - -static int dummy_assign_device (struct domain *d, uint32_t machine_bdf) -{ - return 0; -} - -static int dummy_deassign_device (struct domain *d, uint32_t machine_bdf) -{ - return 0; -} - -static int dummy_resource_plug_core (void) -{ - return 0; -} - -static int dummy_resource_unplug_core (void) -{ - return 0; -} - -static int dummy_resource_plug_pci (uint32_t machine_bdf) -{ - return 0; -} - -static int dummy_resource_unplug_pci (uint32_t machine_bdf) -{ - return 0; -} - -static int dummy_resource_setup_pci (uint32_t machine_bdf) -{ - return 0; -} - -static int dummy_resource_setup_gsi (int gsi) -{ - return 0; -} - -static int dummy_resource_setup_misc (void) -{ - return 0; -} - -static int dummy_page_offline (uint32_t cmd) -{ - return 0; -} - -static int dummy_lockprof (void) -{ - return 0; -} - -static int dummy_cpupool_op (void) -{ - return 0; -} - -static int dummy_sched_op (void) -{ - return 0; -} - -static long dummy___do_xsm_op(XEN_GUEST_HANDLE_PARAM(xsm_op_t) op) -{ - return -ENOSYS; -} - -static char *dummy_show_irq_sid (int irq) -{ - return NULL; -} - -static int dummy_map_domain_pirq (struct domain *d, int irq, void *data) -{ - return 0; -} - -static int dummy_irq_permission (struct domain *d, int pirq, uint8_t allow) -{ - return 0; -} - -static int dummy_iomem_permission (struct domain *d, uint64_t s, uint64_t e, uint8_t allow) -{ - return 0; -} - -static int dummy_pci_config_permission (struct domain *d, uint32_t machine_bdf, - uint16_t start, uint16_t end, - uint8_t access) -{ - return 0; -} - -#ifdef CONFIG_X86 -static int dummy_shadow_control (struct domain *d, uint32_t op) -{ - return 0; -} - -static int dummy_getpageframeinfo (struct domain *d) -{ - return 0; -} - -static int dummy_getmemlist (struct domain *d) -{ - return 0; -} - -static int dummy_hypercall_init (struct domain *d) -{ - return 0; -} - -static int dummy_hvmcontext (struct domain *d, uint32_t cmd) -{ - return 0; -} - -static int dummy_address_size (struct domain *d, uint32_t cmd) -{ - return 0; -} - -static int dummy_machine_address_size (struct domain *d, uint32_t cmd) -{ - return 0; -} - -static int dummy_hvm_param (struct domain *d, unsigned long op) -{ - return 0; -} - -static int dummy_hvm_set_pci_intx_level (struct domain *d) -{ - return 0; -} - -static int dummy_hvm_set_isa_irq_level (struct domain *d) -{ - return 0; -} - -static int dummy_hvm_set_pci_link_route (struct domain *d) -{ - return 0; -} - -static int dummy_hvm_inject_msi (struct domain *d) -{ - return 0; -} - -static int dummy_mem_event (struct domain *d) -{ - return 0; -} - -static int dummy_mem_sharing (struct domain *d) -{ - return 0; -} - -static int dummy_apic (struct domain *d, int cmd) -{ - return 0; -} - -static int dummy_xen_settime (void) -{ - return 0; -} - -static int dummy_memtype (uint32_t access) -{ - return 0; -} - -static int dummy_microcode (void) -{ - return 0; -} - -static int dummy_physinfo (void) -{ - return 0; -} - -static int dummy_platform_quirk (uint32_t quirk) -{ - return 0; -} - -static int dummy_firmware_info (void) -{ - return 0; -} - -static int dummy_efi_call(void) -{ - return 0; -} - -static int dummy_acpi_sleep (void) -{ - return 0; -} - -static int dummy_change_freq (void) -{ - return 0; -} - -static int dummy_getidletime (void) -{ - return 0; -} - -static int dummy_machine_memory_map (void) -{ - return 0; -} - -static int dummy_domain_memory_map (struct domain *d) -{ - return 0; -} - -static int dummy_mmu_normal_update (struct domain *d, struct domain *t, - struct domain *f, intpte_t fpte) -{ - return 0; -} - -static int dummy_mmu_machphys_update (struct domain *d, struct domain *f, unsigned long mfn) -{ - return 0; -} - -static int dummy_update_va_mapping (struct domain *d, struct domain *f, - l1_pgentry_t pte) -{ - return 0; -} - -static int dummy_add_to_physmap (struct domain *d1, struct domain *d2) -{ - return 0; -} - -static int dummy_remove_from_physmap (struct domain *d1, struct domain *d2) -{ - return 0; -} - -static int dummy_sendtrigger (struct domain *d) -{ - return 0; -} - -static int dummy_bind_pt_irq (struct domain *d, struct xen_domctl_bind_pt_irq *bind) -{ - return 0; -} - -static int dummy_unbind_pt_irq (struct domain *d) -{ - return 0; -} - -static int dummy_pin_mem_cacheattr (struct domain *d) -{ - return 0; -} - -static int dummy_ext_vcpucontext (struct domain *d, uint32_t cmd) -{ - return 0; -} - -static int dummy_vcpuextstate (struct domain *d, uint32_t cmd) -{ - return 0; -} - -static int dummy_ioport_permission (struct domain *d, uint32_t s, uint32_t e, uint8_t allow) -{ - return 0; -} -#endif +#define XSM_NO_WRAPPERS +#define XSM_INLINE /* */ +#include <xsm/dummy.h> struct xsm_operations dummy_xsm_ops; @@ -617,7 +20,7 @@ struct xsm_operations dummy_xsm_ops; do { \ if ( !ops->function ) \ { \ - ops->function = dummy_##function; \ + ops->function = xsm_##function; \ if (ops != &dummy_xsm_ops) \ dprintk(XENLOG_DEBUG, "Had to override the " #function \ " security operation with the dummy one.\n"); \ @@ -715,7 +118,7 @@ void xsm_fixup_ops (struct xsm_operations *ops) set_to_dummy_if_null(ops, cpupool_op); set_to_dummy_if_null(ops, sched_op); - set_to_dummy_if_null(ops, __do_xsm_op); + set_to_dummy_if_null(ops, do_xsm_op); #ifdef CONFIG_X86 set_to_dummy_if_null(ops, shadow_control); diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index 782e28c..ead5958 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -1550,7 +1550,7 @@ static struct xsm_operations flask_ops = { .cpupool_op = flask_cpupool_op, .sched_op = flask_sched_op, - .__do_xsm_op = do_flask_op, + .do_xsm_op = do_flask_op, #ifdef CONFIG_X86 .shadow_control = flask_shadow_control, diff --git a/xen/xsm/xsm_core.c b/xen/xsm/xsm_core.c index 46287cb..ca28f91 100644 --- a/xen/xsm/xsm_core.c +++ b/xen/xsm/xsm_core.c @@ -113,7 +113,7 @@ int unregister_xsm(struct xsm_operations *ops) long do_xsm_op (XEN_GUEST_HANDLE_PARAM(xsm_op_t) op) { - return __do_xsm_op(op); + return xsm_do_xsm_op(op); } -- 1.7.11.7
Daniel De Graaf
2013-Jan-10 15:33 UTC
[PATCH 02/22] flask: move policy headers into hypervisor
Rather than keeping around headers that are autogenerated in order to avoid adding build dependencies from xen/ to files in tools/, move the relevant parts of the FLASK policy into the hypervisor tree and generate the headers as part of the hypervisor''s build. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> --- .gitignore | 5 + .hgignore | 5 + tools/flask/policy/Makefile | 2 +- tools/flask/policy/policy/flask/Makefile | 41 ------ xen/xsm/flask/Makefile | 25 ++++ xen/xsm/flask/include/av_perm_to_string.h | 135 ------------------- xen/xsm/flask/include/av_permissions.h | 145 --------------------- xen/xsm/flask/include/class_to_string.h | 15 --- xen/xsm/flask/include/flask.h | 35 ----- xen/xsm/flask/include/initial_sid_to_string.h | 16 --- .../flask => xen/xsm/flask/policy}/access_vectors | 0 .../flask => xen/xsm/flask/policy}/initial_sids | 0 .../xsm/flask/policy}/mkaccess_vector.sh | 4 +- .../flask => xen/xsm/flask/policy}/mkflask.sh | 6 +- .../xsm/flask/policy}/security_classes | 0 15 files changed, 41 insertions(+), 393 deletions(-) delete mode 100644 tools/flask/policy/policy/flask/Makefile delete mode 100644 xen/xsm/flask/include/av_perm_to_string.h delete mode 100644 xen/xsm/flask/include/av_permissions.h delete mode 100644 xen/xsm/flask/include/class_to_string.h delete mode 100644 xen/xsm/flask/include/flask.h delete mode 100644 xen/xsm/flask/include/initial_sid_to_string.h rename {tools/flask/policy/policy/flask => xen/xsm/flask/policy}/access_vectors (100%) rename {tools/flask/policy/policy/flask => xen/xsm/flask/policy}/initial_sids (100%) rename {tools/flask/policy/policy/flask => xen/xsm/flask/policy}/mkaccess_vector.sh (97%) rename {tools/flask/policy/policy/flask => xen/xsm/flask/policy}/mkflask.sh (95%) rename {tools/flask/policy/policy/flask => xen/xsm/flask/policy}/security_classes (100%) diff --git a/.gitignore b/.gitignore index f71cff8..02ea1fa 100644 --- a/.gitignore +++ b/.gitignore @@ -314,6 +314,11 @@ xen/include/xen/banner.h xen/include/xen/compile.h xen/tools/figlet/figlet xen/tools/symbols +xen/xsm/flask/include/av_perm_to_string.h +xen/xsm/flask/include/av_permissions.h +xen/xsm/flask/include/class_to_string.h +xen/xsm/flask/include/flask.h +xen/xsm/flask/include/initial_sid_to_string.h xen/xen xen/xen-syms xen/xen.* diff --git a/.hgignore b/.hgignore index 344792a..5ed903f 100644 --- a/.hgignore +++ b/.hgignore @@ -339,6 +339,11 @@ ^xen/include/xen/compile\.h$ ^xen/tools/figlet/figlet$ ^xen/tools/symbols$ +^xen/xsm/flask/include/av_perm_to_string\.h$ +^xen/xsm/flask/include/av_permissions\.h$ +^xen/xsm/flask/include/class_to_string\.h$ +^xen/xsm/flask/include/flask\.h$ +^xen/xsm/flask/include/initial_sid_to_string\.h$ ^xen/xen$ ^xen/xen-syms$ ^xen/xen\..*$ diff --git a/tools/flask/policy/Makefile b/tools/flask/policy/Makefile index 5c25cbe..3f5aa38 100644 --- a/tools/flask/policy/Makefile +++ b/tools/flask/policy/Makefile @@ -61,7 +61,7 @@ LOADPOLICY := $(SBINDIR)/flask-loadpolicy # policy source layout POLDIR := policy MODDIR := $(POLDIR)/modules -FLASKDIR := $(POLDIR)/flask +FLASKDIR := ../../../xen/xsm/flask/policy SECCLASS := $(FLASKDIR)/security_classes ISIDS := $(FLASKDIR)/initial_sids AVS := $(FLASKDIR)/access_vectors diff --git a/tools/flask/policy/policy/flask/Makefile b/tools/flask/policy/policy/flask/Makefile deleted file mode 100644 index 5f57e88..0000000 --- a/tools/flask/policy/policy/flask/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -# flask needs to know where to export the libselinux headers. -LIBSEL ?= ../../libselinux - -# flask needs to know where to export the kernel headers. -LINUXDIR ?= ../../../linux-2.6 - -AWK = awk - -CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ - else if [ -x /bin/bash ]; then echo /bin/bash; \ - else echo sh; fi ; fi) - -FLASK_H_DEPEND = security_classes initial_sids -AV_H_DEPEND = access_vectors - -FLASK_H_FILES = class_to_string.h flask.h initial_sid_to_string.h -AV_H_FILES = av_perm_to_string.h av_permissions.h -ALL_H_FILES = $(FLASK_H_FILES) $(AV_H_FILES) - -all: $(ALL_H_FILES) - -$(FLASK_H_FILES): $(FLASK_H_DEPEND) - $(CONFIG_SHELL) mkflask.sh $(AWK) $(FLASK_H_DEPEND) - -$(AV_H_FILES): $(AV_H_DEPEND) - $(CONFIG_SHELL) mkaccess_vector.sh $(AWK) $(AV_H_DEPEND) - -tolib: all - install -m 644 flask.h av_permissions.h $(LIBSEL)/include/selinux - install -m 644 class_to_string.h av_inherit.h common_perm_to_string.h av_perm_to_string.h $(LIBSEL)/src - -tokern: all - install -m 644 $(ALL_H_FILES) $(LINUXDIR)/security/selinux/include - -install: all - -relabel: - -clean: - rm -f $(FLASK_H_FILES) - rm -f $(AV_H_FILES) diff --git a/xen/xsm/flask/Makefile b/xen/xsm/flask/Makefile index 92fb410..1256512 100644 --- a/xen/xsm/flask/Makefile +++ b/xen/xsm/flask/Makefile @@ -5,3 +5,28 @@ obj-y += flask_op.o subdir-y += ss CFLAGS += -I./include + +AWK = awk + +CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ + else if [ -x /bin/bash ]; then echo /bin/bash; \ + else echo sh; fi ; fi) + +FLASK_H_DEPEND = policy/security_classes policy/initial_sids +AV_H_DEPEND = policy/access_vectors + +FLASK_H_FILES = include/flask.h include/class_to_string.h include/initial_sid_to_string.h +AV_H_FILES = include/av_perm_to_string.h include/av_permissions.h +ALL_H_FILES = $(FLASK_H_FILES) $(AV_H_FILES) + +$(obj-y) ss/built_in.o: $(ALL_H_FILES) + +$(FLASK_H_FILES): $(FLASK_H_DEPEND) + $(CONFIG_SHELL) policy/mkflask.sh $(AWK) $(FLASK_H_DEPEND) + +$(AV_H_FILES): $(AV_H_DEPEND) + $(CONFIG_SHELL) policy/mkaccess_vector.sh $(AWK) $(AV_H_DEPEND) + +.PHONY: clean +clean:: + rm -f $(ALL_H_FILES) *.o $(DEPS) diff --git a/xen/xsm/flask/include/av_perm_to_string.h b/xen/xsm/flask/include/av_perm_to_string.h deleted file mode 100644 index e7e2058..0000000 --- a/xen/xsm/flask/include/av_perm_to_string.h +++ /dev/null @@ -1,135 +0,0 @@ -/* This file is automatically generated. Do not edit. */ - S_(SECCLASS_XEN, XEN__SCHEDULER, "scheduler") - S_(SECCLASS_XEN, XEN__SETTIME, "settime") - S_(SECCLASS_XEN, XEN__TBUFCONTROL, "tbufcontrol") - S_(SECCLASS_XEN, XEN__READCONSOLE, "readconsole") - S_(SECCLASS_XEN, XEN__CLEARCONSOLE, "clearconsole") - S_(SECCLASS_XEN, XEN__PERFCONTROL, "perfcontrol") - S_(SECCLASS_XEN, XEN__MTRR_ADD, "mtrr_add") - S_(SECCLASS_XEN, XEN__MTRR_DEL, "mtrr_del") - S_(SECCLASS_XEN, XEN__MTRR_READ, "mtrr_read") - S_(SECCLASS_XEN, XEN__MICROCODE, "microcode") - S_(SECCLASS_XEN, XEN__PHYSINFO, "physinfo") - S_(SECCLASS_XEN, XEN__QUIRK, "quirk") - S_(SECCLASS_XEN, XEN__WRITECONSOLE, "writeconsole") - S_(SECCLASS_XEN, XEN__READAPIC, "readapic") - S_(SECCLASS_XEN, XEN__WRITEAPIC, "writeapic") - S_(SECCLASS_XEN, XEN__PRIVPROFILE, "privprofile") - S_(SECCLASS_XEN, XEN__NONPRIVPROFILE, "nonprivprofile") - S_(SECCLASS_XEN, XEN__KEXEC, "kexec") - S_(SECCLASS_XEN, XEN__FIRMWARE, "firmware") - S_(SECCLASS_XEN, XEN__SLEEP, "sleep") - S_(SECCLASS_XEN, XEN__FREQUENCY, "frequency") - S_(SECCLASS_XEN, XEN__GETIDLE, "getidle") - S_(SECCLASS_XEN, XEN__DEBUG, "debug") - S_(SECCLASS_XEN, XEN__GETCPUINFO, "getcpuinfo") - S_(SECCLASS_XEN, XEN__HEAP, "heap") - S_(SECCLASS_XEN, XEN__PM_OP, "pm_op") - S_(SECCLASS_XEN, XEN__MCA_OP, "mca_op") - S_(SECCLASS_XEN, XEN__LOCKPROF, "lockprof") - S_(SECCLASS_XEN, XEN__CPUPOOL_OP, "cpupool_op") - S_(SECCLASS_XEN, XEN__SCHED_OP, "sched_op") - S_(SECCLASS_DOMAIN, DOMAIN__SETVCPUCONTEXT, "setvcpucontext") - S_(SECCLASS_DOMAIN, DOMAIN__PAUSE, "pause") - S_(SECCLASS_DOMAIN, DOMAIN__UNPAUSE, "unpause") - S_(SECCLASS_DOMAIN, DOMAIN__RESUME, "resume") - S_(SECCLASS_DOMAIN, DOMAIN__CREATE, "create") - S_(SECCLASS_DOMAIN, DOMAIN__TRANSITION, "transition") - S_(SECCLASS_DOMAIN, DOMAIN__MAX_VCPUS, "max_vcpus") - S_(SECCLASS_DOMAIN, DOMAIN__DESTROY, "destroy") - S_(SECCLASS_DOMAIN, DOMAIN__SETVCPUAFFINITY, "setvcpuaffinity") - S_(SECCLASS_DOMAIN, DOMAIN__GETVCPUAFFINITY, "getvcpuaffinity") - S_(SECCLASS_DOMAIN, DOMAIN__SCHEDULER, "scheduler") - S_(SECCLASS_DOMAIN, DOMAIN__GETDOMAININFO, "getdomaininfo") - S_(SECCLASS_DOMAIN, DOMAIN__GETVCPUINFO, "getvcpuinfo") - S_(SECCLASS_DOMAIN, DOMAIN__GETVCPUCONTEXT, "getvcpucontext") - S_(SECCLASS_DOMAIN, DOMAIN__SETDOMAINMAXMEM, "setdomainmaxmem") - S_(SECCLASS_DOMAIN, DOMAIN__SETDOMAINHANDLE, "setdomainhandle") - S_(SECCLASS_DOMAIN, DOMAIN__SETDEBUGGING, "setdebugging") - S_(SECCLASS_DOMAIN, DOMAIN__HYPERCALL, "hypercall") - S_(SECCLASS_DOMAIN, DOMAIN__SETTIME, "settime") - S_(SECCLASS_DOMAIN, DOMAIN__SET_TARGET, "set_target") - S_(SECCLASS_DOMAIN, DOMAIN__SHUTDOWN, "shutdown") - S_(SECCLASS_DOMAIN, DOMAIN__SETADDRSIZE, "setaddrsize") - S_(SECCLASS_DOMAIN, DOMAIN__GETADDRSIZE, "getaddrsize") - S_(SECCLASS_DOMAIN, DOMAIN__TRIGGER, "trigger") - S_(SECCLASS_DOMAIN, DOMAIN__GETEXTVCPUCONTEXT, "getextvcpucontext") - S_(SECCLASS_DOMAIN, DOMAIN__SETEXTVCPUCONTEXT, "setextvcpucontext") - S_(SECCLASS_DOMAIN, DOMAIN__GETVCPUEXTSTATE, "getvcpuextstate") - S_(SECCLASS_DOMAIN, DOMAIN__SETVCPUEXTSTATE, "setvcpuextstate") - S_(SECCLASS_DOMAIN, DOMAIN__GETPODTARGET, "getpodtarget") - S_(SECCLASS_DOMAIN, DOMAIN__SETPODTARGET, "setpodtarget") - S_(SECCLASS_DOMAIN, DOMAIN__SET_MISC_INFO, "set_misc_info") - S_(SECCLASS_DOMAIN, DOMAIN__SET_VIRQ_HANDLER, "set_virq_handler") - S_(SECCLASS_DOMAIN2, DOMAIN2__RELABELFROM, "relabelfrom") - S_(SECCLASS_DOMAIN2, DOMAIN2__RELABELTO, "relabelto") - S_(SECCLASS_DOMAIN2, DOMAIN2__RELABELSELF, "relabelself") - S_(SECCLASS_HVM, HVM__SETHVMC, "sethvmc") - S_(SECCLASS_HVM, HVM__GETHVMC, "gethvmc") - S_(SECCLASS_HVM, HVM__SETPARAM, "setparam") - S_(SECCLASS_HVM, HVM__GETPARAM, "getparam") - S_(SECCLASS_HVM, HVM__PCILEVEL, "pcilevel") - S_(SECCLASS_HVM, HVM__IRQLEVEL, "irqlevel") - S_(SECCLASS_HVM, HVM__PCIROUTE, "pciroute") - S_(SECCLASS_HVM, HVM__BIND_IRQ, "bind_irq") - S_(SECCLASS_HVM, HVM__CACHEATTR, "cacheattr") - S_(SECCLASS_HVM, HVM__TRACKDIRTYVRAM, "trackdirtyvram") - S_(SECCLASS_HVM, HVM__HVMCTL, "hvmctl") - S_(SECCLASS_HVM, HVM__MEM_EVENT, "mem_event") - S_(SECCLASS_HVM, HVM__MEM_SHARING, "mem_sharing") - S_(SECCLASS_EVENT, EVENT__BIND, "bind") - S_(SECCLASS_EVENT, EVENT__SEND, "send") - S_(SECCLASS_EVENT, EVENT__STATUS, "status") - S_(SECCLASS_EVENT, EVENT__NOTIFY, "notify") - S_(SECCLASS_EVENT, EVENT__CREATE, "create") - S_(SECCLASS_EVENT, EVENT__RESET, "reset") - S_(SECCLASS_GRANT, GRANT__MAP_READ, "map_read") - S_(SECCLASS_GRANT, GRANT__MAP_WRITE, "map_write") - S_(SECCLASS_GRANT, GRANT__UNMAP, "unmap") - S_(SECCLASS_GRANT, GRANT__TRANSFER, "transfer") - S_(SECCLASS_GRANT, GRANT__SETUP, "setup") - S_(SECCLASS_GRANT, GRANT__COPY, "copy") - S_(SECCLASS_GRANT, GRANT__QUERY, "query") - S_(SECCLASS_MMU, MMU__MAP_READ, "map_read") - S_(SECCLASS_MMU, MMU__MAP_WRITE, "map_write") - S_(SECCLASS_MMU, MMU__PAGEINFO, "pageinfo") - S_(SECCLASS_MMU, MMU__PAGELIST, "pagelist") - S_(SECCLASS_MMU, MMU__ADJUST, "adjust") - S_(SECCLASS_MMU, MMU__STAT, "stat") - S_(SECCLASS_MMU, MMU__TRANSLATEGP, "translategp") - S_(SECCLASS_MMU, MMU__UPDATEMP, "updatemp") - S_(SECCLASS_MMU, MMU__PHYSMAP, "physmap") - S_(SECCLASS_MMU, MMU__PINPAGE, "pinpage") - S_(SECCLASS_MMU, MMU__MFNLIST, "mfnlist") - S_(SECCLASS_MMU, MMU__MEMORYMAP, "memorymap") - S_(SECCLASS_MMU, MMU__REMOTE_REMAP, "remote_remap") - S_(SECCLASS_SHADOW, SHADOW__DISABLE, "disable") - S_(SECCLASS_SHADOW, SHADOW__ENABLE, "enable") - S_(SECCLASS_SHADOW, SHADOW__LOGDIRTY, "logdirty") - S_(SECCLASS_RESOURCE, RESOURCE__ADD, "add") - S_(SECCLASS_RESOURCE, RESOURCE__REMOVE, "remove") - S_(SECCLASS_RESOURCE, RESOURCE__USE, "use") - S_(SECCLASS_RESOURCE, RESOURCE__ADD_IRQ, "add_irq") - S_(SECCLASS_RESOURCE, RESOURCE__REMOVE_IRQ, "remove_irq") - S_(SECCLASS_RESOURCE, RESOURCE__ADD_IOPORT, "add_ioport") - S_(SECCLASS_RESOURCE, RESOURCE__REMOVE_IOPORT, "remove_ioport") - S_(SECCLASS_RESOURCE, RESOURCE__ADD_IOMEM, "add_iomem") - S_(SECCLASS_RESOURCE, RESOURCE__REMOVE_IOMEM, "remove_iomem") - S_(SECCLASS_RESOURCE, RESOURCE__STAT_DEVICE, "stat_device") - S_(SECCLASS_RESOURCE, RESOURCE__ADD_DEVICE, "add_device") - S_(SECCLASS_RESOURCE, RESOURCE__REMOVE_DEVICE, "remove_device") - S_(SECCLASS_RESOURCE, RESOURCE__PLUG, "plug") - S_(SECCLASS_RESOURCE, RESOURCE__UNPLUG, "unplug") - S_(SECCLASS_RESOURCE, RESOURCE__SETUP, "setup") - S_(SECCLASS_SECURITY, SECURITY__COMPUTE_AV, "compute_av") - S_(SECCLASS_SECURITY, SECURITY__COMPUTE_CREATE, "compute_create") - S_(SECCLASS_SECURITY, SECURITY__COMPUTE_MEMBER, "compute_member") - S_(SECCLASS_SECURITY, SECURITY__CHECK_CONTEXT, "check_context") - S_(SECCLASS_SECURITY, SECURITY__LOAD_POLICY, "load_policy") - S_(SECCLASS_SECURITY, SECURITY__COMPUTE_RELABEL, "compute_relabel") - S_(SECCLASS_SECURITY, SECURITY__COMPUTE_USER, "compute_user") - S_(SECCLASS_SECURITY, SECURITY__SETENFORCE, "setenforce") - S_(SECCLASS_SECURITY, SECURITY__SETBOOL, "setbool") - S_(SECCLASS_SECURITY, SECURITY__SETSECPARAM, "setsecparam") - S_(SECCLASS_SECURITY, SECURITY__ADD_OCONTEXT, "add_ocontext") - S_(SECCLASS_SECURITY, SECURITY__DEL_OCONTEXT, "del_ocontext") diff --git a/xen/xsm/flask/include/av_permissions.h b/xen/xsm/flask/include/av_permissions.h deleted file mode 100644 index cb1c5dc..0000000 --- a/xen/xsm/flask/include/av_permissions.h +++ /dev/null @@ -1,145 +0,0 @@ -/* This file is automatically generated. Do not edit. */ -#define XEN__SCHEDULER 0x00000001UL -#define XEN__SETTIME 0x00000002UL -#define XEN__TBUFCONTROL 0x00000004UL -#define XEN__READCONSOLE 0x00000008UL -#define XEN__CLEARCONSOLE 0x00000010UL -#define XEN__PERFCONTROL 0x00000020UL -#define XEN__MTRR_ADD 0x00000040UL -#define XEN__MTRR_DEL 0x00000080UL -#define XEN__MTRR_READ 0x00000100UL -#define XEN__MICROCODE 0x00000200UL -#define XEN__PHYSINFO 0x00000400UL -#define XEN__QUIRK 0x00000800UL -#define XEN__WRITECONSOLE 0x00001000UL -#define XEN__READAPIC 0x00002000UL -#define XEN__WRITEAPIC 0x00004000UL -#define XEN__PRIVPROFILE 0x00008000UL -#define XEN__NONPRIVPROFILE 0x00010000UL -#define XEN__KEXEC 0x00020000UL -#define XEN__FIRMWARE 0x00040000UL -#define XEN__SLEEP 0x00080000UL -#define XEN__FREQUENCY 0x00100000UL -#define XEN__GETIDLE 0x00200000UL -#define XEN__DEBUG 0x00400000UL -#define XEN__GETCPUINFO 0x00800000UL -#define XEN__HEAP 0x01000000UL -#define XEN__PM_OP 0x02000000UL -#define XEN__MCA_OP 0x04000000UL -#define XEN__LOCKPROF 0x08000000UL -#define XEN__CPUPOOL_OP 0x10000000UL -#define XEN__SCHED_OP 0x20000000UL - -#define DOMAIN__SETVCPUCONTEXT 0x00000001UL -#define DOMAIN__PAUSE 0x00000002UL -#define DOMAIN__UNPAUSE 0x00000004UL -#define DOMAIN__RESUME 0x00000008UL -#define DOMAIN__CREATE 0x00000010UL -#define DOMAIN__TRANSITION 0x00000020UL -#define DOMAIN__MAX_VCPUS 0x00000040UL -#define DOMAIN__DESTROY 0x00000080UL -#define DOMAIN__SETVCPUAFFINITY 0x00000100UL -#define DOMAIN__GETVCPUAFFINITY 0x00000200UL -#define DOMAIN__SCHEDULER 0x00000400UL -#define DOMAIN__GETDOMAININFO 0x00000800UL -#define DOMAIN__GETVCPUINFO 0x00001000UL -#define DOMAIN__GETVCPUCONTEXT 0x00002000UL -#define DOMAIN__SETDOMAINMAXMEM 0x00004000UL -#define DOMAIN__SETDOMAINHANDLE 0x00008000UL -#define DOMAIN__SETDEBUGGING 0x00010000UL -#define DOMAIN__HYPERCALL 0x00020000UL -#define DOMAIN__SETTIME 0x00040000UL -#define DOMAIN__SET_TARGET 0x00080000UL -#define DOMAIN__SHUTDOWN 0x00100000UL -#define DOMAIN__SETADDRSIZE 0x00200000UL -#define DOMAIN__GETADDRSIZE 0x00400000UL -#define DOMAIN__TRIGGER 0x00800000UL -#define DOMAIN__GETEXTVCPUCONTEXT 0x01000000UL -#define DOMAIN__SETEXTVCPUCONTEXT 0x02000000UL -#define DOMAIN__GETVCPUEXTSTATE 0x04000000UL -#define DOMAIN__SETVCPUEXTSTATE 0x08000000UL -#define DOMAIN__GETPODTARGET 0x10000000UL -#define DOMAIN__SETPODTARGET 0x20000000UL -#define DOMAIN__SET_MISC_INFO 0x40000000UL -#define DOMAIN__SET_VIRQ_HANDLER 0x80000000UL - -#define DOMAIN2__RELABELFROM 0x00000001UL -#define DOMAIN2__RELABELTO 0x00000002UL -#define DOMAIN2__RELABELSELF 0x00000004UL - -#define HVM__SETHVMC 0x00000001UL -#define HVM__GETHVMC 0x00000002UL -#define HVM__SETPARAM 0x00000004UL -#define HVM__GETPARAM 0x00000008UL -#define HVM__PCILEVEL 0x00000010UL -#define HVM__IRQLEVEL 0x00000020UL -#define HVM__PCIROUTE 0x00000040UL -#define HVM__BIND_IRQ 0x00000080UL -#define HVM__CACHEATTR 0x00000100UL -#define HVM__TRACKDIRTYVRAM 0x00000200UL -#define HVM__HVMCTL 0x00000400UL -#define HVM__MEM_EVENT 0x00000800UL -#define HVM__MEM_SHARING 0x00001000UL - -#define EVENT__BIND 0x00000001UL -#define EVENT__SEND 0x00000002UL -#define EVENT__STATUS 0x00000004UL -#define EVENT__NOTIFY 0x00000008UL -#define EVENT__CREATE 0x00000010UL -#define EVENT__RESET 0x00000020UL - -#define GRANT__MAP_READ 0x00000001UL -#define GRANT__MAP_WRITE 0x00000002UL -#define GRANT__UNMAP 0x00000004UL -#define GRANT__TRANSFER 0x00000008UL -#define GRANT__SETUP 0x00000010UL -#define GRANT__COPY 0x00000020UL -#define GRANT__QUERY 0x00000040UL - -#define MMU__MAP_READ 0x00000001UL -#define MMU__MAP_WRITE 0x00000002UL -#define MMU__PAGEINFO 0x00000004UL -#define MMU__PAGELIST 0x00000008UL -#define MMU__ADJUST 0x00000010UL -#define MMU__STAT 0x00000020UL -#define MMU__TRANSLATEGP 0x00000040UL -#define MMU__UPDATEMP 0x00000080UL -#define MMU__PHYSMAP 0x00000100UL -#define MMU__PINPAGE 0x00000200UL -#define MMU__MFNLIST 0x00000400UL -#define MMU__MEMORYMAP 0x00000800UL -#define MMU__REMOTE_REMAP 0x00001000UL - -#define SHADOW__DISABLE 0x00000001UL -#define SHADOW__ENABLE 0x00000002UL -#define SHADOW__LOGDIRTY 0x00000004UL - -#define RESOURCE__ADD 0x00000001UL -#define RESOURCE__REMOVE 0x00000002UL -#define RESOURCE__USE 0x00000004UL -#define RESOURCE__ADD_IRQ 0x00000008UL -#define RESOURCE__REMOVE_IRQ 0x00000010UL -#define RESOURCE__ADD_IOPORT 0x00000020UL -#define RESOURCE__REMOVE_IOPORT 0x00000040UL -#define RESOURCE__ADD_IOMEM 0x00000080UL -#define RESOURCE__REMOVE_IOMEM 0x00000100UL -#define RESOURCE__STAT_DEVICE 0x00000200UL -#define RESOURCE__ADD_DEVICE 0x00000400UL -#define RESOURCE__REMOVE_DEVICE 0x00000800UL -#define RESOURCE__PLUG 0x00001000UL -#define RESOURCE__UNPLUG 0x00002000UL -#define RESOURCE__SETUP 0x00004000UL - -#define SECURITY__COMPUTE_AV 0x00000001UL -#define SECURITY__COMPUTE_CREATE 0x00000002UL -#define SECURITY__COMPUTE_MEMBER 0x00000004UL -#define SECURITY__CHECK_CONTEXT 0x00000008UL -#define SECURITY__LOAD_POLICY 0x00000010UL -#define SECURITY__COMPUTE_RELABEL 0x00000020UL -#define SECURITY__COMPUTE_USER 0x00000040UL -#define SECURITY__SETENFORCE 0x00000080UL -#define SECURITY__SETBOOL 0x00000100UL -#define SECURITY__SETSECPARAM 0x00000200UL -#define SECURITY__ADD_OCONTEXT 0x00000400UL -#define SECURITY__DEL_OCONTEXT 0x00000800UL - diff --git a/xen/xsm/flask/include/class_to_string.h b/xen/xsm/flask/include/class_to_string.h deleted file mode 100644 index 7716645..0000000 --- a/xen/xsm/flask/include/class_to_string.h +++ /dev/null @@ -1,15 +0,0 @@ -/* This file is automatically generated. Do not edit. */ -/* - * Security object class definitions - */ - S_("null") - S_("xen") - S_("domain") - S_("domain2") - S_("hvm") - S_("mmu") - S_("resource") - S_("shadow") - S_("event") - S_("grant") - S_("security") diff --git a/xen/xsm/flask/include/flask.h b/xen/xsm/flask/include/flask.h deleted file mode 100644 index 3bff998..0000000 --- a/xen/xsm/flask/include/flask.h +++ /dev/null @@ -1,35 +0,0 @@ -/* This file is automatically generated. Do not edit. */ -#ifndef _SELINUX_FLASK_H_ -#define _SELINUX_FLASK_H_ - -/* - * Security object class definitions - */ -#define SECCLASS_XEN 1 -#define SECCLASS_DOMAIN 2 -#define SECCLASS_DOMAIN2 3 -#define SECCLASS_HVM 4 -#define SECCLASS_MMU 5 -#define SECCLASS_RESOURCE 6 -#define SECCLASS_SHADOW 7 -#define SECCLASS_EVENT 8 -#define SECCLASS_GRANT 9 -#define SECCLASS_SECURITY 10 - -/* - * Security identifier indices for initial entities - */ -#define SECINITSID_XEN 1 -#define SECINITSID_DOM0 2 -#define SECINITSID_DOMIO 3 -#define SECINITSID_DOMXEN 4 -#define SECINITSID_UNLABELED 5 -#define SECINITSID_SECURITY 6 -#define SECINITSID_IOPORT 7 -#define SECINITSID_IOMEM 8 -#define SECINITSID_IRQ 9 -#define SECINITSID_DEVICE 10 - -#define SECINITSID_NUM 10 - -#endif diff --git a/xen/xsm/flask/include/initial_sid_to_string.h b/xen/xsm/flask/include/initial_sid_to_string.h deleted file mode 100644 index 814f4bf..0000000 --- a/xen/xsm/flask/include/initial_sid_to_string.h +++ /dev/null @@ -1,16 +0,0 @@ -/* This file is automatically generated. Do not edit. */ -static char *initial_sid_to_string[] -{ - "null", - "xen", - "dom0", - "domio", - "domxen", - "unlabeled", - "security", - "ioport", - "iomem", - "irq", - "device", -}; - diff --git a/tools/flask/policy/policy/flask/access_vectors b/xen/xsm/flask/policy/access_vectors similarity index 100% rename from tools/flask/policy/policy/flask/access_vectors rename to xen/xsm/flask/policy/access_vectors diff --git a/tools/flask/policy/policy/flask/initial_sids b/xen/xsm/flask/policy/initial_sids similarity index 100% rename from tools/flask/policy/policy/flask/initial_sids rename to xen/xsm/flask/policy/initial_sids diff --git a/tools/flask/policy/policy/flask/mkaccess_vector.sh b/xen/xsm/flask/policy/mkaccess_vector.sh similarity index 97% rename from tools/flask/policy/policy/flask/mkaccess_vector.sh rename to xen/xsm/flask/policy/mkaccess_vector.sh index 43a60a7..8ec87f7 100644 --- a/tools/flask/policy/policy/flask/mkaccess_vector.sh +++ b/xen/xsm/flask/policy/mkaccess_vector.sh @@ -9,8 +9,8 @@ awk=$1 shift # output files -av_permissions="av_permissions.h" -av_perm_to_string="av_perm_to_string.h" +av_permissions="include/av_permissions.h" +av_perm_to_string="include/av_perm_to_string.h" cat $* | $awk " BEGIN { diff --git a/tools/flask/policy/policy/flask/mkflask.sh b/xen/xsm/flask/policy/mkflask.sh similarity index 95% rename from tools/flask/policy/policy/flask/mkflask.sh rename to xen/xsm/flask/policy/mkflask.sh index 9c84754..e8d8fb5 100644 --- a/tools/flask/policy/policy/flask/mkflask.sh +++ b/xen/xsm/flask/policy/mkflask.sh @@ -9,9 +9,9 @@ awk=$1 shift 1 # output file -output_file="flask.h" -debug_file="class_to_string.h" -debug_file2="initial_sid_to_string.h" +output_file="include/flask.h" +debug_file="include/class_to_string.h" +debug_file2="include/initial_sid_to_string.h" cat $* | $awk " BEGIN { diff --git a/tools/flask/policy/policy/flask/security_classes b/xen/xsm/flask/policy/security_classes similarity index 100% rename from tools/flask/policy/policy/flask/security_classes rename to xen/xsm/flask/policy/security_classes -- 1.7.11.7
Daniel De Graaf
2013-Jan-10 15:33 UTC
[PATCH 03/22] arch/x86: add distinct XSM hooks for map/unmap
The xsm_iomem_permission and xsm_ioport_permission hooks are intended to be called by the domain builder, while the calls in arch/x86/domctl.c which control mapping are also performed by the device model. Because these operations require distinct access control policies, they cannot use the same XSM hooks. This also adds a missing XSM hook in the unbind IRQ domctl. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Acked-by: Jan Beulich <jbeulich@suse.com> Cc: Keir Fraser <keir@xen.org> --- xen/arch/x86/domctl.c | 8 ++++++-- xen/arch/x86/physdev.c | 2 +- xen/include/xsm/dummy.h | 17 ++++++++++++++++- xen/include/xsm/xsm.h | 25 ++++++++++++++++++++++--- xen/xsm/dummy.c | 3 +++ xen/xsm/flask/hooks.c | 43 +++++++++++++++++++++---------------------- 6 files changed, 69 insertions(+), 29 deletions(-) diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c index e89a20a..0e81010 100644 --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -656,6 +656,10 @@ long arch_do_domctl( !irq_access_permitted(current->domain, bind->machine_irq) ) break; + ret = xsm_unbind_pt_irq(d, bind); + if ( ret ) + break; + if ( iommu_enabled ) { spin_lock(&pcidevs_lock); @@ -687,7 +691,7 @@ long arch_do_domctl( !iomem_access_permitted(current->domain, mfn, mfn + nr_mfns - 1) ) break; - ret = xsm_iomem_permission(d, mfn, mfn + nr_mfns - 1, add); + ret = xsm_iomem_mapping(d, mfn, mfn + nr_mfns - 1, add); if ( ret ) break; @@ -765,7 +769,7 @@ long arch_do_domctl( !ioports_access_permitted(current->domain, fmp, fmp + np - 1) ) break; - ret = xsm_ioport_permission(d, fmp, fmp + np - 1, add); + ret = xsm_ioport_mapping(d, fmp, fmp + np - 1, add); if ( ret ) break; diff --git a/xen/arch/x86/physdev.c b/xen/arch/x86/physdev.c index a041783..7800473 100644 --- a/xen/arch/x86/physdev.c +++ b/xen/arch/x86/physdev.c @@ -242,7 +242,7 @@ int physdev_unmap_pirq(domid_t domid, int pirq) if ( !IS_PRIV_FOR(current->domain, d) ) goto free_domain; - ret = xsm_irq_permission(d, domain_pirq_to_irq(d, pirq), 0); + ret = xsm_unmap_domain_pirq(d, domain_pirq_to_irq(d, pirq)); if ( ret ) goto free_domain; diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index 075572f..4384552 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -394,6 +394,11 @@ static XSM_INLINE int xsm_map_domain_pirq(struct domain *d, int irq, void *data) return 0; } +static XSM_INLINE int xsm_unmap_domain_pirq(struct domain *d, int irq) +{ + return 0; +} + static XSM_INLINE int xsm_irq_permission(struct domain *d, int pirq, uint8_t allow) { return 0; @@ -404,6 +409,11 @@ static XSM_INLINE int xsm_iomem_permission(struct domain *d, uint64_t s, uint64_ return 0; } +static XSM_INLINE int xsm_iomem_mapping(struct domain *d, uint64_t s, uint64_t e, uint8_t allow) +{ + return 0; +} + static XSM_INLINE int xsm_pci_config_permission(struct domain *d, uint32_t machine_bdf, uint16_t start, uint16_t end, uint8_t access) @@ -585,7 +595,7 @@ static XSM_INLINE int xsm_bind_pt_irq(struct domain *d, struct xen_domctl_bind_p return 0; } -static XSM_INLINE int xsm_unbind_pt_irq(struct domain *d) +static XSM_INLINE int xsm_unbind_pt_irq(struct domain *d, struct xen_domctl_bind_pt_irq *bind) { return 0; } @@ -610,4 +620,9 @@ static XSM_INLINE int xsm_ioport_permission(struct domain *d, uint32_t s, uint32 return 0; } +static XSM_INLINE int xsm_ioport_mapping(struct domain *d, uint32_t s, uint32_t e, uint8_t allow) +{ + return 0; +} + #endif diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index 73169fe..662f233 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -111,8 +111,10 @@ struct xsm_operations { char *(*show_irq_sid) (int irq); int (*map_domain_pirq) (struct domain *d, int irq, void *data); + int (*unmap_domain_pirq) (struct domain *d, int irq); int (*irq_permission) (struct domain *d, int pirq, uint8_t allow); int (*iomem_permission) (struct domain *d, uint64_t s, uint64_t e, uint8_t allow); + int (*iomem_mapping) (struct domain *d, uint64_t s, uint64_t e, uint8_t allow); int (*pci_config_permission) (struct domain *d, uint32_t machine_bdf, uint16_t start, uint16_t end, uint8_t access); int (*get_device_group) (uint32_t machine_bdf); @@ -170,11 +172,12 @@ struct xsm_operations { int (*add_to_physmap) (struct domain *d1, struct domain *d2); int (*sendtrigger) (struct domain *d); int (*bind_pt_irq) (struct domain *d, struct xen_domctl_bind_pt_irq *bind); - int (*unbind_pt_irq) (struct domain *d); + int (*unbind_pt_irq) (struct domain *d, struct xen_domctl_bind_pt_irq *bind); int (*pin_mem_cacheattr) (struct domain *d); int (*ext_vcpucontext) (struct domain *d, uint32_t cmd); int (*vcpuextstate) (struct domain *d, uint32_t cmd); int (*ioport_permission) (struct domain *d, uint32_t s, uint32_t e, uint8_t allow); + int (*ioport_mapping) (struct domain *d, uint32_t s, uint32_t e, uint8_t allow); #endif }; @@ -489,6 +492,11 @@ static inline int xsm_map_domain_pirq (struct domain *d, int irq, void *data) return xsm_ops->map_domain_pirq(d, irq, data); } +static inline int xsm_unmap_domain_pirq (struct domain *d, int irq) +{ + return xsm_ops->unmap_domain_pirq(d, irq); +} + static inline int xsm_irq_permission (struct domain *d, int pirq, uint8_t allow) { return xsm_ops->irq_permission(d, pirq, allow); @@ -499,6 +507,11 @@ static inline int xsm_iomem_permission (struct domain *d, uint64_t s, uint64_t e return xsm_ops->iomem_permission(d, s, e, allow); } +static inline int xsm_iomem_mapping (struct domain *d, uint64_t s, uint64_t e, uint8_t allow) +{ + return xsm_ops->iomem_mapping(d, s, e, allow); +} + static inline int xsm_pci_config_permission (struct domain *d, uint32_t machine_bdf, uint16_t start, uint16_t end, uint8_t access) { return xsm_ops->pci_config_permission(d, machine_bdf, start, end, access); @@ -754,9 +767,10 @@ static inline int xsm_bind_pt_irq(struct domain *d, return xsm_ops->bind_pt_irq(d, bind); } -static inline int xsm_unbind_pt_irq(struct domain *d) +static inline int xsm_unbind_pt_irq(struct domain *d, + struct xen_domctl_bind_pt_irq *bind) { - return xsm_ops->unbind_pt_irq(d); + return xsm_ops->unbind_pt_irq(d, bind); } static inline int xsm_pin_mem_cacheattr(struct domain *d) @@ -777,6 +791,11 @@ static inline int xsm_ioport_permission (struct domain *d, uint32_t s, uint32_t { return xsm_ops->ioport_permission(d, s, e, allow); } + +static inline int xsm_ioport_mapping (struct domain *d, uint32_t s, uint32_t e, uint8_t allow) +{ + return xsm_ops->ioport_mapping(d, s, e, allow); +} #endif /* CONFIG_X86 */ #endif /* XSM_NO_WRAPPERS */ diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c index a2ce733..b767cfe 100644 --- a/xen/xsm/dummy.c +++ b/xen/xsm/dummy.c @@ -96,8 +96,10 @@ void xsm_fixup_ops (struct xsm_operations *ops) set_to_dummy_if_null(ops, show_irq_sid); set_to_dummy_if_null(ops, map_domain_pirq); + set_to_dummy_if_null(ops, unmap_domain_pirq); set_to_dummy_if_null(ops, irq_permission); set_to_dummy_if_null(ops, iomem_permission); + set_to_dummy_if_null(ops, iomem_mapping); set_to_dummy_if_null(ops, pci_config_permission); set_to_dummy_if_null(ops, get_device_group); @@ -160,5 +162,6 @@ void xsm_fixup_ops (struct xsm_operations *ops) set_to_dummy_if_null(ops, ext_vcpucontext); set_to_dummy_if_null(ops, vcpuextstate); set_to_dummy_if_null(ops, ioport_permission); + set_to_dummy_if_null(ops, ioport_mapping); #endif } diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index ead5958..e60c6f4 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -721,43 +721,41 @@ static int flask_map_domain_pirq (struct domain *d, int irq, void *data) return rc; } -static int flask_irq_permission (struct domain *d, int irq, uint8_t access) +static int flask_unmap_domain_pirq (struct domain *d, int irq) { - u32 perm; - u32 rsid; + u32 sid; int rc = -EPERM; - struct domain_security_struct *ssec, *tsec; + struct domain_security_struct *ssec; struct avc_audit_data ad; - rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE, - resource_to_perm(access)); - + rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE, RESOURCE__REMOVE); if ( rc ) return rc; - if ( access ) - perm = RESOURCE__ADD_IRQ; - else - perm = RESOURCE__REMOVE_IRQ; - ssec = current->domain->ssid; - tsec = d->ssid; - rc = get_irq_sid(irq, &rsid, &ad); - if ( rc ) - return rc; - - rc = avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, perm, &ad); + if ( irq < nr_static_irqs ) { + rc = get_irq_sid(irq, &sid, &ad); + } else { + /* It is currently not possible to check the specific MSI IRQ being + * removed, since we do not have the msi_info like map_domain_pirq */ + return 0; + } if ( rc ) return rc; - if ( access ) - rc = avc_has_perm(tsec->sid, rsid, SECCLASS_RESOURCE, - RESOURCE__USE, &ad); + rc = avc_has_perm(ssec->sid, sid, SECCLASS_RESOURCE, RESOURCE__REMOVE_IRQ, &ad); return rc; } +static int flask_irq_permission (struct domain *d, int pirq, uint8_t access) +{ + /* the PIRQ number is not useful; real IRQ is checked during mapping */ + return domain_has_perm(current->domain, d, SECCLASS_RESOURCE, + resource_to_perm(access)); +} + struct iomem_has_perm_data { struct domain_security_struct *ssec, *tsec; u32 perm; @@ -1413,7 +1411,7 @@ static int flask_bind_pt_irq (struct domain *d, struct xen_domctl_bind_pt_irq *b return avc_has_perm(tsec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__USE, &ad); } -static int flask_unbind_pt_irq (struct domain *d) +static int flask_unbind_pt_irq (struct domain *d, struct xen_domctl_bind_pt_irq *bind) { return domain_has_perm(current->domain, d, SECCLASS_RESOURCE, RESOURCE__REMOVE); } @@ -1533,6 +1531,7 @@ static struct xsm_operations flask_ops = { .show_irq_sid = flask_show_irq_sid, .map_domain_pirq = flask_map_domain_pirq, + .unmap_domain_pirq = flask_unmap_domain_pirq, .irq_permission = flask_irq_permission, .iomem_permission = flask_iomem_permission, .pci_config_permission = flask_pci_config_permission, -- 1.7.11.7
Daniel De Graaf
2013-Jan-10 15:33 UTC
[PATCH 04/22] xen: use XSM instead of IS_PRIV where duplicated
The Xen hypervisor has two basic access control function calls: IS_PRIV and the xsm_* functions. Most privileged operations currently require that both checks succeed, and many times the checks are at different locations in the code. This patch eliminates the explicit and implicit IS_PRIV checks that are duplicated in XSM hooks. When XSM_ENABLE is not defined or when the dummy XSM module is used, this patch should not change any functionality. Because the locations of privilege checks have sometimes moved below argument validation, error returns of some functions may change from EPERM to EINVAL or ESRCH if called with invalid arguments and from a domain without permission to perform the operation. Some checks are removed due to non-obvious duplicates in their callers: * acpi_enter_sleep is checked in XENPF_enter_acpi_sleep * map_domain_pirq has IS_PRIV_FOR checked in its callers: * physdev_map_pirq checks when acquiring the RCU lock * ioapic_guest_write is checked in PHYSDEVOP_apic_write * PHYSDEVOP_{manage_pci_add,manage_pci_add_ext,pci_device_add} are checked by xsm_resource_plug_pci in pci_add_device * PHYSDEVOP_manage_pci_remove is checked by xsm_resource_unplug_pci in pci_remove_device * PHYSDEVOP_{restore_msi,restore_msi_ext} are checked by xsm_resource_setup_pci in pci_restore_msi_state * do_console_io has changed to IS_PRIV from an explicit domid==0 Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Acked-by: Jan Beulich <jbeulich@suse.com> Cc: Keir Fraser <keir@xen.org> --- xen/arch/x86/acpi/power.c | 2 +- xen/arch/x86/cpu/mcheck/mce.c | 3 --- xen/arch/x86/irq.c | 3 +-- xen/arch/x86/mm.c | 3 --- xen/arch/x86/physdev.c | 56 ++++--------------------------------------- xen/common/kexec.c | 3 --- xen/common/schedule.c | 6 ----- xen/drivers/char/console.c | 6 ----- xen/include/xsm/dummy.h | 28 ++++++++++++++++++++++ xen/xsm/flask/hooks.c | 5 ++-- 10 files changed, 37 insertions(+), 78 deletions(-) diff --git a/xen/arch/x86/acpi/power.c b/xen/arch/x86/acpi/power.c index e60173f..c693bd9 100644 --- a/xen/arch/x86/acpi/power.c +++ b/xen/arch/x86/acpi/power.c @@ -239,7 +239,7 @@ static long enter_state_helper(void *data) */ int acpi_enter_sleep(struct xenpf_enter_acpi_sleep *sleep) { - if ( !IS_PRIV(current->domain) || !acpi_sinfo.pm1a_cnt_blk.address ) + if ( !acpi_sinfo.pm1a_cnt_blk.address ) return -EPERM; /* Sanity check */ diff --git a/xen/arch/x86/cpu/mcheck/mce.c b/xen/arch/x86/cpu/mcheck/mce.c index 8b54240..658774a 100644 --- a/xen/arch/x86/cpu/mcheck/mce.c +++ b/xen/arch/x86/cpu/mcheck/mce.c @@ -1293,9 +1293,6 @@ long do_mca(XEN_GUEST_HANDLE_PARAM(xen_mc_t) u_xen_mc) struct xen_mc_msrinject *mc_msrinject; struct xen_mc_mceinject *mc_mceinject; - if (!IS_PRIV(v->domain) ) - return x86_mcerr(NULL, -EPERM); - ret = xsm_do_mca(); if ( ret ) return x86_mcerr(NULL, ret); diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index 05cede5..238600a 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -1853,8 +1853,7 @@ int map_domain_pirq( ASSERT(spin_is_locked(&d->event_lock)); if ( !IS_PRIV(current->domain) && - !(IS_PRIV_FOR(current->domain, d) && - irq_access_permitted(current->domain, pirq))) + !irq_access_permitted(current->domain, pirq)) return -EPERM; if ( pirq < 0 || pirq >= d->nr_pirqs || irq < 0 || irq >= nr_irqs ) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index da34570..56c55e7 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -4493,9 +4493,6 @@ long arch_memory_op(int op, XEN_GUEST_HANDLE_PARAM(void) arg) XEN_GUEST_HANDLE_PARAM(e820entry_t) buffer_param; unsigned int i; - if ( !IS_PRIV(current->domain) ) - return -EINVAL; - rc = xsm_machine_memory_map(); if ( rc ) return rc; diff --git a/xen/arch/x86/physdev.c b/xen/arch/x86/physdev.c index 7800473..32a861a 100644 --- a/xen/arch/x86/physdev.c +++ b/xen/arch/x86/physdev.c @@ -109,12 +109,6 @@ int physdev_map_pirq(domid_t domid, int type, int *index, int *pirq_p, if ( ret ) return ret; - if ( !IS_PRIV_FOR(current->domain, d) ) - { - ret = -EPERM; - goto free_domain; - } - /* Verify or get irq. */ switch ( type ) { @@ -238,10 +232,6 @@ int physdev_unmap_pirq(domid_t domid, int pirq) goto free_domain; } - ret = -EPERM; - if ( !IS_PRIV_FOR(current->domain, d) ) - goto free_domain; - ret = xsm_unmap_domain_pirq(d, domain_pirq_to_irq(d, pirq)); if ( ret ) goto free_domain; @@ -433,9 +423,6 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) ret = -EFAULT; if ( copy_from_guest(&apic, arg, 1) != 0 ) break; - ret = -EPERM; - if ( !IS_PRIV(v->domain) ) - break; ret = xsm_apic(v->domain, cmd); if ( ret ) break; @@ -450,9 +437,6 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) ret = -EFAULT; if ( copy_from_guest(&apic, arg, 1) != 0 ) break; - ret = -EPERM; - if ( !IS_PRIV(v->domain) ) - break; ret = xsm_apic(v->domain, cmd); if ( ret ) break; @@ -467,8 +451,10 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) if ( copy_from_guest(&irq_op, arg, 1) != 0 ) break; - ret = -EPERM; - if ( !IS_PRIV(v->domain) ) + /* Use the APIC check since this dummy hypercall should still only + * be called by the domain with access to program the ioapic */ + ret = xsm_apic(v->domain, cmd); + if ( ret ) break; /* Vector is only used by hypervisor, and dom0 shouldn''t @@ -517,9 +503,6 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) case PHYSDEVOP_manage_pci_add: { struct physdev_manage_pci manage_pci; - ret = -EPERM; - if ( !IS_PRIV(v->domain) ) - break; ret = -EFAULT; if ( copy_from_guest(&manage_pci, arg, 1) != 0 ) break; @@ -530,9 +513,6 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) case PHYSDEVOP_manage_pci_remove: { struct physdev_manage_pci manage_pci; - ret = -EPERM; - if ( !IS_PRIV(v->domain) ) - break; ret = -EFAULT; if ( copy_from_guest(&manage_pci, arg, 1) != 0 ) break; @@ -545,10 +525,6 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) struct physdev_manage_pci_ext manage_pci_ext; struct pci_dev_info pdev_info; - ret = -EPERM; - if ( !IS_PRIV(current->domain) ) - break; - ret = -EFAULT; if ( copy_from_guest(&manage_pci_ext, arg, 1) != 0 ) break; @@ -571,10 +547,6 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) struct physdev_pci_device_add add; struct pci_dev_info pdev_info; - ret = -EPERM; - if ( !IS_PRIV(current->domain) ) - break; - ret = -EFAULT; if ( copy_from_guest(&add, arg, 1) != 0 ) break; @@ -595,10 +567,6 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) case PHYSDEVOP_pci_device_remove: { struct physdev_pci_device dev; - ret = -EPERM; - if ( !IS_PRIV(v->domain) ) - break; - ret = -EFAULT; if ( copy_from_guest(&dev, arg, 1) != 0 ) break; @@ -610,10 +578,6 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) case PHYSDEVOP_pci_mmcfg_reserved: { struct physdev_pci_mmcfg_reserved info; - ret = -EPERM; - if ( !IS_PRIV(current->domain) ) - break; - ret = xsm_resource_setup_misc(); if ( ret ) break; @@ -631,10 +595,6 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) struct physdev_restore_msi restore_msi; struct pci_dev *pdev; - ret = -EPERM; - if ( !IS_PRIV(v->domain) ) - break; - ret = -EFAULT; if ( copy_from_guest(&restore_msi, arg, 1) != 0 ) break; @@ -650,10 +610,6 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) struct physdev_pci_device dev; struct pci_dev *pdev; - ret = -EPERM; - if ( !IS_PRIV(v->domain) ) - break; - ret = -EFAULT; if ( copy_from_guest(&dev, arg, 1) != 0 ) break; @@ -668,10 +624,6 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) case PHYSDEVOP_setup_gsi: { struct physdev_setup_gsi setup_gsi; - ret = -EPERM; - if ( !IS_PRIV(v->domain) ) - break; - ret = -EFAULT; if ( copy_from_guest(&setup_gsi, arg, 1) != 0 ) break; diff --git a/xen/common/kexec.c b/xen/common/kexec.c index 25ebd6a..d4f6332 100644 --- a/xen/common/kexec.c +++ b/xen/common/kexec.c @@ -852,9 +852,6 @@ static int do_kexec_op_internal(unsigned long op, unsigned long flags; int ret = -EINVAL; - if ( !IS_PRIV(current->domain) ) - return -EPERM; - ret = xsm_kexec(); if ( ret ) return ret; diff --git a/xen/common/schedule.c b/xen/common/schedule.c index ae798c9..d405081 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -921,12 +921,6 @@ ret_t do_sched_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) if ( d == NULL ) break; - if ( !IS_PRIV_FOR(current->domain, d) ) - { - rcu_unlock_domain(d); - return -EPERM; - } - ret = xsm_schedop_shutdown(current->domain, d); if ( ret ) { diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c index ff360fe..b2c3ee3 100644 --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -406,12 +406,6 @@ long do_console_io(int cmd, int count, XEN_GUEST_HANDLE_PARAM(char) buffer) long rc; unsigned int idx, len; -#ifndef VERBOSE - /* Only domain 0 may access the emergency console. */ - if ( current->domain->domain_id != 0 ) - return -EPERM; -#endif - rc = xsm_console_io(current->domain, cmd); if ( rc ) return rc; diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index 4384552..fb00a01 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -161,6 +161,8 @@ static XSM_INLINE int xsm_pm_op(void) static XSM_INLINE int xsm_do_mca(void) { + if ( !IS_PRIV(current->domain) ) + return -EPERM; return 0; } @@ -223,6 +225,10 @@ static XSM_INLINE int xsm_memory_stat_reservation(struct domain *d1, struct doma static XSM_INLINE int xsm_console_io(struct domain *d, int cmd) { +#ifndef VERBOSE + if ( !IS_PRIV(current->domain) ) + return -EPERM; +#endif return 0; } @@ -233,11 +239,15 @@ static XSM_INLINE int xsm_profile(struct domain *d, int op) static XSM_INLINE int xsm_kexec(void) { + if ( !IS_PRIV(current->domain) ) + return -EPERM; return 0; } static XSM_INLINE int xsm_schedop_shutdown(struct domain *d1, struct domain *d2) { + if ( !IS_PRIV_FOR(d1, d2) ) + return -EPERM; return 0; } @@ -336,26 +346,36 @@ static XSM_INLINE int xsm_resource_unplug_core(void) static XSM_INLINE int xsm_resource_plug_pci(uint32_t machine_bdf) { + if ( !IS_PRIV(current->domain) ) + return -EPERM; return 0; } static XSM_INLINE int xsm_resource_unplug_pci(uint32_t machine_bdf) { + if ( !IS_PRIV(current->domain) ) + return -EPERM; return 0; } static XSM_INLINE int xsm_resource_setup_pci(uint32_t machine_bdf) { + if ( !IS_PRIV(current->domain) ) + return -EPERM; return 0; } static XSM_INLINE int xsm_resource_setup_gsi(int gsi) { + if ( !IS_PRIV(current->domain) ) + return -EPERM; return 0; } static XSM_INLINE int xsm_resource_setup_misc(void) { + if ( !IS_PRIV(current->domain) ) + return -EPERM; return 0; } @@ -396,6 +416,8 @@ static XSM_INLINE int xsm_map_domain_pirq(struct domain *d, int irq, void *data) static XSM_INLINE int xsm_unmap_domain_pirq(struct domain *d, int irq) { + if ( !IS_PRIV_FOR(current->domain, d) ) + return -EPERM; return 0; } @@ -494,6 +516,8 @@ static XSM_INLINE int xsm_mem_sharing(struct domain *d) static XSM_INLINE int xsm_apic(struct domain *d, int cmd) { + if ( !IS_PRIV(d) ) + return -EPERM; return 0; } @@ -534,6 +558,8 @@ static XSM_INLINE int xsm_efi_call(void) static XSM_INLINE int xsm_acpi_sleep(void) { + if ( !IS_PRIV(current->domain) ) + return -EPERM; return 0; } @@ -549,6 +575,8 @@ static XSM_INLINE int xsm_getidletime(void) static XSM_INLINE int xsm_machine_memory_map(void) { + if ( !IS_PRIV(current->domain) ) + return -EPERM; return 0; } diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index e60c6f4..c8a7999 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -1141,10 +1141,11 @@ static int flask_apic(struct domain *d, int cmd) switch ( cmd ) { - case PHYSDEVOP_APIC_READ: + case PHYSDEVOP_apic_read: + case PHYSDEVOP_alloc_irq_vector: perm = XEN__READAPIC; break; - case PHYSDEVOP_APIC_WRITE: + case PHYSDEVOP_apic_write: perm = XEN__WRITEAPIC; break; default: -- 1.7.11.7
Daniel De Graaf
2013-Jan-10 15:33 UTC
[PATCH 05/22] xen: avoid calling rcu_lock_*target_domain when an XSM hook exists
The rcu_lock_{,remote_}target_domain_by_id functions are wrappers around an IS_PRIV_FOR check for the current domain. This is now redundant with XSM hooks, so replace these calls with rcu_lock_domain_by_any_id or rcu_lock_remote_domain_by_id to remove the duplicate permission checks. When XSM_ENABLE is not defined or when the dummy XSM module is used, this patch should not change any functionality. Because the locations of privilege checks have sometimes moved below argument validation, error returns of some functions may change from EPERM to EINVAL when called with invalid arguments and from a domain without permission to perform the operation. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Acked-by: Jan Beulich <jbeulich@suse.com> Cc: Keir Fraser <keir@xen.org> --- xen/arch/x86/hvm/hvm.c | 38 +++++++++++++++---------------- xen/arch/x86/mm.c | 22 ++++++++---------- xen/common/event_channel.c | 18 +++++++-------- xen/common/grant_table.c | 57 +++++++++++++++------------------------------- xen/common/memory.c | 15 ++++++------ xen/include/xsm/dummy.h | 34 +++++++++++++++++++++++++++ 6 files changed, 97 insertions(+), 87 deletions(-) diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 40c1ab2..fa61d7c 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -3386,7 +3386,7 @@ static int hvmop_set_pci_intx_level( if ( (op.domain > 0) || (op.bus > 0) || (op.device > 31) || (op.intx > 3) ) return -EINVAL; - rc = rcu_lock_remote_target_domain_by_id(op.domid, &d); + rc = rcu_lock_remote_domain_by_id(op.domid, &d); if ( rc != 0 ) return rc; @@ -3553,7 +3553,7 @@ static int hvmop_set_isa_irq_level( if ( op.isa_irq > 15 ) return -EINVAL; - rc = rcu_lock_remote_target_domain_by_id(op.domid, &d); + rc = rcu_lock_remote_domain_by_id(op.domid, &d); if ( rc != 0 ) return rc; @@ -3597,7 +3597,7 @@ static int hvmop_set_pci_link_route( if ( (op.link > 3) || (op.isa_irq > 15) ) return -EINVAL; - rc = rcu_lock_remote_target_domain_by_id(op.domid, &d); + rc = rcu_lock_remote_domain_by_id(op.domid, &d); if ( rc != 0 ) return rc; @@ -3627,7 +3627,7 @@ static int hvmop_inject_msi( if ( copy_from_guest(&op, uop, 1) ) return -EFAULT; - rc = rcu_lock_remote_target_domain_by_id(op.domid, &d); + rc = rcu_lock_remote_domain_by_id(op.domid, &d); if ( rc != 0 ) return rc; @@ -3724,9 +3724,9 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) if ( a.index >= HVM_NR_PARAMS ) return -EINVAL; - rc = rcu_lock_target_domain_by_id(a.domid, &d); - if ( rc != 0 ) - return rc; + d = rcu_lock_domain_by_any_id(a.domid); + if ( d == NULL ) + return -ESRCH; rc = -EINVAL; if ( !is_hvm_domain(d) ) @@ -3970,7 +3970,7 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) if ( copy_from_guest(&a, arg, 1) ) return -EFAULT; - rc = rcu_lock_remote_target_domain_by_id(a.domid, &d); + rc = rcu_lock_remote_domain_by_id(a.domid, &d); if ( rc != 0 ) return rc; @@ -4011,7 +4011,7 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) if ( copy_from_guest(&a, arg, 1) ) return -EFAULT; - rc = rcu_lock_remote_target_domain_by_id(a.domid, &d); + rc = rcu_lock_remote_domain_by_id(a.domid, &d); if ( rc != 0 ) return rc; @@ -4076,9 +4076,9 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) if ( copy_from_guest(&a, arg, 1) ) return -EFAULT; - rc = rcu_lock_target_domain_by_id(a.domid, &d); - if ( rc != 0 ) - return rc; + d = rcu_lock_domain_by_any_id(a.domid); + if ( d == NULL ) + return -ESRCH; rc = xsm_hvm_param(d, op); if ( rc ) @@ -4126,7 +4126,7 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) if ( copy_from_guest(&a, arg, 1) ) return -EFAULT; - rc = rcu_lock_remote_target_domain_by_id(a.domid, &d); + rc = rcu_lock_remote_domain_by_id(a.domid, &d); if ( rc != 0 ) return rc; @@ -4219,7 +4219,7 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) if ( copy_from_guest(&a, arg, 1) ) return -EFAULT; - rc = rcu_lock_remote_target_domain_by_id(a.domid, &d); + rc = rcu_lock_remote_domain_by_id(a.domid, &d); if ( rc != 0 ) return rc; @@ -4254,7 +4254,7 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) if ( copy_from_guest(&a, arg, 1) ) return -EFAULT; - rc = rcu_lock_remote_target_domain_by_id(a.domid, &d); + rc = rcu_lock_remote_domain_by_id(a.domid, &d); if ( rc != 0 ) return rc; @@ -4290,9 +4290,9 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) if ( copy_from_guest(&a, arg, 1) ) return -EFAULT; - rc = rcu_lock_target_domain_by_id(a.domid, &d); - if ( rc != 0 ) - return rc; + d = rcu_lock_domain_by_any_id(a.domid); + if ( d == NULL ) + return -ESRCH; rc = -EINVAL; if ( !is_hvm_domain(d) || !paging_mode_shadow(d) ) @@ -4344,7 +4344,7 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) if ( copy_from_guest(&tr, arg, 1 ) ) return -EFAULT; - rc = rcu_lock_remote_target_domain_by_id(tr.domid, &d); + rc = rcu_lock_remote_domain_by_id(tr.domid, &d); if ( rc != 0 ) return rc; diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 56c55e7..717fe68 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -4375,9 +4375,9 @@ long arch_memory_op(int op, XEN_GUEST_HANDLE_PARAM(void) arg) if ( copy_from_guest(&xatp, arg, 1) ) return -EFAULT; - rc = rcu_lock_target_domain_by_id(xatp.domid, &d); - if ( rc != 0 ) - return rc; + d = rcu_lock_domain_by_any_id(xatp.domid); + if ( d == NULL ) + return -ESRCH; if ( xsm_add_to_physmap(current->domain, d) ) { @@ -4414,9 +4414,9 @@ long arch_memory_op(int op, XEN_GUEST_HANDLE_PARAM(void) arg) if ( fmap.map.nr_entries > E820MAX ) return -EINVAL; - rc = rcu_lock_target_domain_by_id(fmap.domid, &d); - if ( rc != 0 ) - return rc; + d = rcu_lock_domain_by_any_id(fmap.domid); + if ( d == NULL ) + return -ESRCH; rc = xsm_domain_memory_map(d); if ( rc ) @@ -4569,16 +4569,12 @@ long arch_memory_op(int op, XEN_GUEST_HANDLE_PARAM(void) arg) struct domain *d; struct p2m_domain *p2m; - /* Support DOMID_SELF? */ - if ( !IS_PRIV(current->domain) ) - return -EPERM; - if ( copy_from_guest(&target, arg, 1) ) return -EFAULT; - rc = rcu_lock_target_domain_by_id(target.domid, &d); - if ( rc != 0 ) - return rc; + d = rcu_lock_domain_by_any_id(target.domid); + if ( d == NULL ) + return -ESRCH; if ( op == XENMEM_set_pod_target ) rc = xsm_set_pod_target(d); diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c index 89f0ca7..f620966 100644 --- a/xen/common/event_channel.c +++ b/xen/common/event_channel.c @@ -165,9 +165,9 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc) domid_t dom = alloc->dom; long rc; - rc = rcu_lock_target_domain_by_id(dom, &d); - if ( rc ) - return rc; + d = rcu_lock_domain_by_any_id(dom); + if ( d == NULL ) + return -ESRCH; spin_lock(&d->event_lock); @@ -798,9 +798,9 @@ static long evtchn_status(evtchn_status_t *status) struct evtchn *chn; long rc = 0; - rc = rcu_lock_target_domain_by_id(dom, &d); - if ( rc ) - return rc; + d = rcu_lock_domain_by_any_id(dom); + if ( d == NULL ) + return -ESRCH; spin_lock(&d->event_lock); @@ -950,9 +950,9 @@ static long evtchn_reset(evtchn_reset_t *r) struct domain *d; int i, rc; - rc = rcu_lock_target_domain_by_id(dom, &d); - if ( rc ) - return rc; + d = rcu_lock_domain_by_any_id(dom); + if ( d == NULL ) + return -ESRCH; rc = xsm_evtchn_reset(current->domain, d); if ( rc ) diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index ce66d75..59708c3 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -230,30 +230,6 @@ double_gt_unlock(struct grant_table *lgt, struct grant_table *rgt) spin_unlock(&rgt->lock); } -static struct domain *gt_lock_target_domain_by_id(domid_t dom) -{ - struct domain *d; - int rc = GNTST_general_error; - - switch ( rcu_lock_target_domain_by_id(dom, &d) ) - { - case 0: - return d; - - case -ESRCH: - gdprintk(XENLOG_INFO, "Bad domid %d.\n", dom); - rc = GNTST_bad_domain; - break; - - case -EPERM: - rc = GNTST_permission_denied; - break; - } - - ASSERT(rc < 0 && -rc <= MAX_ERRNO); - return ERR_PTR(rc); -} - static inline int __get_maptrack_handle( struct grant_table *t) @@ -1352,11 +1328,12 @@ gnttab_setup_table( if ( !guest_handle_okay(op.frame_list, op.nr_frames) ) return -EFAULT; - d = gt_lock_target_domain_by_id(op.dom); - if ( IS_ERR(d) ) + d = rcu_lock_domain_by_any_id(op.dom); + if ( d == NULL ) { - op.status = PTR_ERR(d); - goto out1; + gdprintk(XENLOG_INFO, "Bad domid %d.\n", op.dom); + op.status = GNTST_bad_domain; + goto out2; } if ( xsm_grant_setup(current->domain, d) ) @@ -1421,10 +1398,11 @@ gnttab_query_size( return -EFAULT; } - d = gt_lock_target_domain_by_id(op.dom); - if ( IS_ERR(d) ) + d = rcu_lock_domain_by_any_id(op.dom); + if ( d == NULL ) { - op.status = PTR_ERR(d); + gdprintk(XENLOG_INFO, "Bad domid %d.\n", op.dom); + op.status = GNTST_bad_domain; goto query_out; } @@ -2296,10 +2274,10 @@ gnttab_get_status_frames(XEN_GUEST_HANDLE_PARAM(gnttab_get_status_frames_t) uop, return -EFAULT; } - d = gt_lock_target_domain_by_id(op.dom); - if ( IS_ERR(d) ) + d = rcu_lock_domain_by_any_id(op.dom); + if ( d == NULL ) { - op.status = PTR_ERR(d); + op.status = GNTST_bad_domain; goto out1; } rc = xsm_grant_setup(current->domain, d); @@ -2349,14 +2327,15 @@ gnttab_get_version(XEN_GUEST_HANDLE_PARAM(gnttab_get_version_t) uop) if ( copy_from_guest(&op, uop, 1) ) return -EFAULT; - rc = rcu_lock_target_domain_by_id(op.dom, &d); - if ( rc < 0 ) - return rc; + d = rcu_lock_domain_by_any_id(op.dom); + if ( d == NULL ) + return -ESRCH; - if ( xsm_grant_query_size(current->domain, d) ) + rc = xsm_grant_query_size(current->domain, d); + if ( rc ) { rcu_unlock_domain(d); - return -EPERM; + return rc; } op.version = d->grant_table->gt_version; diff --git a/xen/common/memory.c b/xen/common/memory.c index c8c1ef2..35acf1c 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -585,7 +585,8 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg) && (reservation.mem_flags & XENMEMF_populate_on_demand) ) args.memflags |= MEMF_populate_on_demand; - if ( unlikely(rcu_lock_target_domain_by_id(reservation.domid, &d)) ) + d = rcu_lock_domain_by_any_id(reservation.domid); + if ( d == NULL ) return start_extent; args.domain = d; @@ -634,9 +635,9 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg) if ( copy_from_guest(&domid, arg, 1) ) return -EFAULT; - rc = rcu_lock_target_domain_by_id(domid, &d); - if ( rc ) - return rc; + d = rcu_lock_domain_by_any_id(domid); + if ( d == NULL ) + return -ESRCH; rc = xsm_memory_stat_reservation(current->domain, d); if ( rc ) @@ -672,9 +673,9 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg) if ( copy_from_guest(&xrfp, arg, 1) ) return -EFAULT; - rc = rcu_lock_target_domain_by_id(xrfp.domid, &d); - if ( rc != 0 ) - return rc; + d = rcu_lock_domain_by_any_id(xrfp.domid); + if ( d == NULL ) + return -ESRCH; if ( xsm_remove_from_physmap(current->domain, d) ) { diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index fb00a01..dc16684 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -194,6 +194,8 @@ static XSM_INLINE int xsm_grant_unmapref(struct domain *d1, struct domain *d2) static XSM_INLINE int xsm_grant_setup(struct domain *d1, struct domain *d2) { + if ( d1 != d2 && !IS_PRIV_FOR(d1, d2) ) + return -EPERM; return 0; } @@ -209,17 +211,23 @@ static XSM_INLINE int xsm_grant_copy(struct domain *d1, struct domain *d2) static XSM_INLINE int xsm_grant_query_size(struct domain *d1, struct domain *d2) { + if ( d1 != d2 && !IS_PRIV_FOR(d1, d2) ) + return -EPERM; return 0; } static XSM_INLINE int xsm_memory_adjust_reservation(struct domain *d1, struct domain *d2) { + if ( d1 != d2 && !IS_PRIV_FOR(d1, d2) ) + return -EPERM; return 0; } static XSM_INLINE int xsm_memory_stat_reservation(struct domain *d1, struct domain *d2) { + if ( d1 != d2 && !IS_PRIV_FOR(d1, d2) ) + return -EPERM; return 0; } @@ -260,6 +268,8 @@ static XSM_INLINE int xsm_memory_pin_page(struct domain *d1, struct domain *d2, static XSM_INLINE int xsm_evtchn_unbound(struct domain *d, struct evtchn *chn, domid_t id2) { + if ( current->domain != d && !IS_PRIV_FOR(current->domain, d) ) + return -EPERM; return 0; } @@ -281,11 +291,15 @@ static XSM_INLINE int xsm_evtchn_send(struct domain *d, struct evtchn *chn) static XSM_INLINE int xsm_evtchn_status(struct domain *d, struct evtchn *chn) { + if ( current->domain != d && !IS_PRIV_FOR(current->domain, d) ) + return -EPERM; return 0; } static XSM_INLINE int xsm_evtchn_reset(struct domain *d1, struct domain *d2) { + if ( d1 != d2 && !IS_PRIV_FOR(d1, d2) ) + return -EPERM; return 0; } @@ -306,11 +320,15 @@ static XSM_INLINE char *xsm_show_security_evtchn(struct domain *d, const struct static XSM_INLINE int xsm_get_pod_target(struct domain *d) { + if ( !IS_PRIV(current->domain) ) + return -EPERM; return 0; } static XSM_INLINE int xsm_set_pod_target(struct domain *d) { + if ( !IS_PRIV(current->domain) ) + return -EPERM; return 0; } @@ -481,26 +499,36 @@ static XSM_INLINE int xsm_machine_address_size(struct domain *d, uint32_t cmd) static XSM_INLINE int xsm_hvm_param(struct domain *d, unsigned long op) { + if ( current->domain != d && !IS_PRIV_FOR(current->domain, d) ) + return -EPERM; return 0; } static XSM_INLINE int xsm_hvm_set_pci_intx_level(struct domain *d) { + if ( !IS_PRIV_FOR(current->domain, d) ) + return -EPERM; return 0; } static XSM_INLINE int xsm_hvm_set_isa_irq_level(struct domain *d) { + if ( !IS_PRIV_FOR(current->domain, d) ) + return -EPERM; return 0; } static XSM_INLINE int xsm_hvm_set_pci_link_route(struct domain *d) { + if ( !IS_PRIV_FOR(current->domain, d) ) + return -EPERM; return 0; } static XSM_INLINE int xsm_hvm_inject_msi(struct domain *d) { + if ( !IS_PRIV_FOR(current->domain, d) ) + return -EPERM; return 0; } @@ -582,6 +610,8 @@ static XSM_INLINE int xsm_machine_memory_map(void) static XSM_INLINE int xsm_domain_memory_map(struct domain *d) { + if ( current->domain != d && !IS_PRIV_FOR(current->domain, d) ) + return -EPERM; return 0; } @@ -605,11 +635,15 @@ static XSM_INLINE int xsm_update_va_mapping(struct domain *d, struct domain *f, static XSM_INLINE int xsm_add_to_physmap(struct domain *d1, struct domain *d2) { + if ( d1 != d2 && !IS_PRIV_FOR(d1, d2) ) + return -EPERM; return 0; } static XSM_INLINE int xsm_remove_from_physmap(struct domain *d1, struct domain *d2) { + if ( d1 != d2 && !IS_PRIV_FOR(d1, d2) ) + return -EPERM; return 0; } -- 1.7.11.7
The xsm_domctl hook now covers every domctl, in addition to the more fine-grained XSM hooks in most sub-functions. This also removes the need to special-case XEN_DOMCTL_getdomaininfo. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Cc: Keir Fraser <keir@xen.org> Cc: Jan Beulich <jbeulich@suse.com> --- xen/common/domctl.c | 32 +++---------------- xen/include/xsm/dummy.h | 16 ++++++++-- xen/xsm/flask/hooks.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 103 insertions(+), 30 deletions(-) diff --git a/xen/common/domctl.c b/xen/common/domctl.c index 05d9c55..b32e614 100644 --- a/xen/common/domctl.c +++ b/xen/common/domctl.c @@ -265,27 +265,9 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) return -ESRCH; } - switch ( op->cmd ) - { - case XEN_DOMCTL_ioport_mapping: - case XEN_DOMCTL_memory_mapping: - case XEN_DOMCTL_bind_pt_irq: - case XEN_DOMCTL_unbind_pt_irq: { - bool_t is_priv = IS_PRIV_FOR(current->domain, d); - if ( !is_priv ) - { - ret = -EPERM; - goto domctl_out_unlock_domonly; - } - break; - } - case XEN_DOMCTL_getdomaininfo: - break; - default: - if ( !IS_PRIV(current->domain) ) - return -EPERM; - break; - } + ret = xsm_domctl(d, op->cmd); + if ( ret ) + goto domctl_out_unlock_domonly; if ( !domctl_lock_acquire() ) { @@ -855,17 +837,13 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) case XEN_DOMCTL_subscribe: { - ret = xsm_domctl(d, op->cmd); - if ( !ret ) - d->suspend_evtchn = op->u.subscribe.port; + d->suspend_evtchn = op->u.subscribe.port; } break; case XEN_DOMCTL_disable_migrate: { - ret = xsm_domctl(d, op->cmd); - if ( !ret ) - d->disable_migrate = op->u.disable_migrate.disable; + d->disable_migrate = op->u.disable_migrate.disable; } break; diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index dc16684..93b1148 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -64,8 +64,6 @@ static XSM_INLINE int xsm_scheduler(struct domain *d) static XSM_INLINE int xsm_getdomaininfo(struct domain *d) { - if ( !IS_PRIV(current->domain) ) - return -EPERM; return 0; } @@ -91,6 +89,20 @@ static XSM_INLINE int xsm_set_target(struct domain *d, struct domain *e) static XSM_INLINE int xsm_domctl(struct domain *d, int cmd) { + switch ( cmd ) + { + case XEN_DOMCTL_ioport_mapping: + case XEN_DOMCTL_memory_mapping: + case XEN_DOMCTL_bind_pt_irq: + case XEN_DOMCTL_unbind_pt_irq: { + if ( !IS_PRIV_FOR(current->domain, d) ) + return -EPERM; + break; + } + default: + if ( !IS_PRIV(current->domain) ) + return -EPERM; + } return 0; } diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index c8a7999..fe7178c 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -582,7 +582,90 @@ static int flask_set_target(struct domain *d, struct domain *e) static int flask_domctl(struct domain *d, int cmd) { - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__SET_MISC_INFO); + switch ( cmd ) + { + /* These have individual XSM hooks (common/domctl.c) */ + case XEN_DOMCTL_createdomain: + case XEN_DOMCTL_destroydomain: + case XEN_DOMCTL_pausedomain: + case XEN_DOMCTL_unpausedomain: + case XEN_DOMCTL_getdomaininfo: + case XEN_DOMCTL_setvcpuaffinity: + case XEN_DOMCTL_max_mem: + case XEN_DOMCTL_setvcpucontext: + case XEN_DOMCTL_getvcpucontext: + case XEN_DOMCTL_getvcpuinfo: + case XEN_DOMCTL_max_vcpus: + case XEN_DOMCTL_scheduler_op: + case XEN_DOMCTL_setdomainhandle: + case XEN_DOMCTL_setdebugging: + case XEN_DOMCTL_irq_permission: + case XEN_DOMCTL_iomem_permission: + case XEN_DOMCTL_settimeoffset: + case XEN_DOMCTL_getvcpuaffinity: + case XEN_DOMCTL_resumedomain: + case XEN_DOMCTL_set_target: + case XEN_DOMCTL_set_virq_handler: +#ifdef CONFIG_X86 + /* These have individual XSM hooks (arch/x86/domctl.c) */ + case XEN_DOMCTL_shadow_op: + case XEN_DOMCTL_ioport_permission: + case XEN_DOMCTL_getpageframeinfo: + case XEN_DOMCTL_getpageframeinfo2: + case XEN_DOMCTL_getpageframeinfo3: + case XEN_DOMCTL_getmemlist: + case XEN_DOMCTL_hypercall_init: + case XEN_DOMCTL_sethvmcontext: + case XEN_DOMCTL_gethvmcontext: + case XEN_DOMCTL_gethvmcontext_partial: + case XEN_DOMCTL_set_address_size: + case XEN_DOMCTL_get_address_size: + case XEN_DOMCTL_set_machine_address_size: + case XEN_DOMCTL_get_machine_address_size: + case XEN_DOMCTL_sendtrigger: + case XEN_DOMCTL_bind_pt_irq: + case XEN_DOMCTL_unbind_pt_irq: + case XEN_DOMCTL_memory_mapping: + case XEN_DOMCTL_ioport_mapping: + case XEN_DOMCTL_pin_mem_cacheattr: + case XEN_DOMCTL_set_ext_vcpucontext: + case XEN_DOMCTL_get_ext_vcpucontext: + case XEN_DOMCTL_setvcpuextstate: + case XEN_DOMCTL_getvcpuextstate: + case XEN_DOMCTL_mem_event_op: + case XEN_DOMCTL_mem_sharing_op: + case XEN_DOMCTL_set_access_required: + /* These have individual XSM hooks (drivers/passthrough/iommu.c) */ + case XEN_DOMCTL_get_device_group: + case XEN_DOMCTL_test_assign_device: + case XEN_DOMCTL_assign_device: + case XEN_DOMCTL_deassign_device: +#endif + return 0; + + case XEN_DOMCTL_subscribe: + case XEN_DOMCTL_disable_migrate: + return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, + DOMAIN__SET_MISC_INFO); + + case XEN_DOMCTL_set_cpuid: + case XEN_DOMCTL_suppress_spurious_page_faults: + case XEN_DOMCTL_debug_op: + case XEN_DOMCTL_gettscinfo: + case XEN_DOMCTL_settscinfo: + case XEN_DOMCTL_audit_p2m: + case XEN_DOMCTL_gdbsx_guestmemio: + case XEN_DOMCTL_gdbsx_pausevcpu: + case XEN_DOMCTL_gdbsx_unpausevcpu: + case XEN_DOMCTL_gdbsx_domstatus: + /* TODO add per-subfunction hooks */ + if ( !IS_PRIV(current->domain) ) + return -EPERM; + return 0; + default: + printk("flask_domctl: Unknown op %d\n", cmd); + return -EPERM; + } } static int flask_set_virq_handler(struct domain *d, uint32_t virq) -- 1.7.11.7
The xsm_sysctl hook now covers every sysctl, in addition to the more fine-grained XSM hooks in most sub-functions. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Cc: Keir Fraser <keir@xen.org> Cc: Jan Beulich <jbeulich@suse.com> --- xen/common/sysctl.c | 7 ++++--- xen/include/xsm/dummy.h | 7 +++++++ xen/include/xsm/xsm.h | 6 ++++++ xen/xsm/dummy.c | 1 + xen/xsm/flask/hooks.c | 33 +++++++++++++++++++++++++++++++++ 5 files changed, 51 insertions(+), 3 deletions(-) diff --git a/xen/common/sysctl.c b/xen/common/sysctl.c index 261b3c4..61e7a29 100644 --- a/xen/common/sysctl.c +++ b/xen/common/sysctl.c @@ -34,15 +34,16 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl) struct xen_sysctl curop, *op = &curop; static DEFINE_SPINLOCK(sysctl_lock); - if ( !IS_PRIV(current->domain) ) - return -EPERM; - if ( copy_from_guest(op, u_sysctl, 1) ) return -EFAULT; if ( op->interface_version != XEN_SYSCTL_INTERFACE_VERSION ) return -EACCES; + ret = xsm_sysctl(op->cmd); + if ( ret ) + return ret; + /* * Trylock here avoids deadlock with an existing sysctl critical section * which might (for some current or future reason) want to synchronise diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index 93b1148..b335bd9 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -106,6 +106,13 @@ static XSM_INLINE int xsm_domctl(struct domain *d, int cmd) return 0; } +static XSM_INLINE int xsm_sysctl(int cmd) +{ + if ( !IS_PRIV(current->domain) ) + return -EPERM; + return 0; +} + static XSM_INLINE int xsm_set_virq_handler(struct domain *d, uint32_t virq) { return 0; diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index 662f233..75c27bb 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -58,6 +58,7 @@ struct xsm_operations { int (*domain_settime) (struct domain *d); int (*set_target) (struct domain *d, struct domain *e); int (*domctl) (struct domain *d, int cmd); + int (*sysctl) (int cmd); int (*set_virq_handler) (struct domain *d, uint32_t virq); int (*tbufcontrol) (void); int (*readconsole) (uint32_t clear); @@ -266,6 +267,11 @@ static inline int xsm_domctl (struct domain *d, int cmd) return xsm_ops->domctl(d, cmd); } +static inline int xsm_sysctl (int cmd) +{ + return xsm_ops->sysctl(cmd); +} + static inline int xsm_set_virq_handler (struct domain *d, uint32_t virq) { return xsm_ops->set_virq_handler(d, virq); diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c index b767cfe..f6a0807 100644 --- a/xen/xsm/dummy.c +++ b/xen/xsm/dummy.c @@ -45,6 +45,7 @@ void xsm_fixup_ops (struct xsm_operations *ops) set_to_dummy_if_null(ops, domain_settime); set_to_dummy_if_null(ops, set_target); set_to_dummy_if_null(ops, domctl); + set_to_dummy_if_null(ops, sysctl); set_to_dummy_if_null(ops, set_virq_handler); set_to_dummy_if_null(ops, tbufcontrol); set_to_dummy_if_null(ops, readconsole); diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index fe7178c..b3698c7 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -668,6 +668,38 @@ static int flask_domctl(struct domain *d, int cmd) } } +static int flask_sysctl(int cmd) +{ + switch ( cmd ) + { + /* These have individual XSM hooks */ + case XEN_SYSCTL_readconsole: + case XEN_SYSCTL_tbuf_op: + case XEN_SYSCTL_sched_id: + case XEN_SYSCTL_perfc_op: + case XEN_SYSCTL_getdomaininfolist: + case XEN_SYSCTL_debug_keys: + case XEN_SYSCTL_getcpuinfo: + case XEN_SYSCTL_availheap: + case XEN_SYSCTL_get_pmstat: + case XEN_SYSCTL_pm_op: + case XEN_SYSCTL_page_offline_op: + case XEN_SYSCTL_lockprof_op: + case XEN_SYSCTL_cpupool_op: + case XEN_SYSCTL_scheduler_op: +#ifdef CONFIG_X86 + case XEN_SYSCTL_physinfo: + case XEN_SYSCTL_cpu_hotplug: + case XEN_SYSCTL_topologyinfo: + case XEN_SYSCTL_numainfo: +#endif + return 0; + default: + printk("flask_sysctl: Unknown op %d\n", cmd); + return -EPERM; + } +} + static int flask_set_virq_handler(struct domain *d, uint32_t virq) { return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__SET_VIRQ_HANDLER); @@ -1563,6 +1595,7 @@ static struct xsm_operations flask_ops = { .domain_settime = flask_domain_settime, .set_target = flask_set_target, .domctl = flask_domctl, + .sysctl = flask_sysctl, .set_virq_handler = flask_set_virq_handler, .tbufcontrol = flask_tbufcontrol, .readconsole = flask_readconsole, -- 1.7.11.7
Daniel De Graaf
2013-Jan-10 15:33 UTC
[PATCH 08/22] arch/x86: convert platform_hypercall to use XSM
The newly introduced xsm_platform_op hook addresses new sub-ops, while most ops already have their own XSM hooks. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Acked-by: Jan Beulich <jbeulich@suse.com> Cc: Keir Fraser <keir@xen.org> --- xen/arch/x86/platform_hypercall.c | 11 ++++++++--- xen/include/xsm/dummy.h | 7 +++++++ xen/include/xsm/xsm.h | 6 ++++++ xen/xsm/dummy.c | 1 + xen/xsm/flask/hooks.c | 33 +++++++++++++++++++++++++++++++++ 5 files changed, 55 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c index 56e2994..570b3db 100644 --- a/xen/arch/x86/platform_hypercall.c +++ b/xen/arch/x86/platform_hypercall.c @@ -66,15 +66,16 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) ret_t ret = 0; struct xen_platform_op curop, *op = &curop; - if ( !IS_PRIV(current->domain) ) - return -EPERM; - if ( copy_from_guest(op, u_xenpf_op, 1) ) return -EFAULT; if ( op->interface_version != XENPF_INTERFACE_VERSION ) return -EACCES; + ret = xsm_platform_op(op->cmd); + if ( ret ) + return ret; + /* * Trylock here avoids deadlock with an existing platform critical section * which might (for some current or future reason) want to synchronise @@ -513,6 +514,10 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) { struct xenpf_pcpu_version *ver = &op->u.pcpu_version; + ret = xsm_getcpuinfo(); + if ( ret ) + break; + if ( !get_cpu_maps() ) { ret = -EBUSY; diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index b335bd9..e42965c 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -593,6 +593,13 @@ static XSM_INLINE int xsm_platform_quirk(uint32_t quirk) return 0; } +static XSM_INLINE int xsm_platform_op(uint32_t op) +{ + if ( !IS_PRIV(current->domain) ) + return -EPERM; + return 0; +} + static XSM_INLINE int xsm_firmware_info(void) { return 0; diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index 75c27bb..470e3c0 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -159,6 +159,7 @@ struct xsm_operations { int (*microcode) (void); int (*physinfo) (void); int (*platform_quirk) (uint32_t); + int (*platform_op) (uint32_t cmd); int (*firmware_info) (void); int (*efi_call) (void); int (*acpi_sleep) (void); @@ -704,6 +705,11 @@ static inline int xsm_platform_quirk (uint32_t quirk) return xsm_ops->platform_quirk(quirk); } +static inline int xsm_platform_op (uint32_t op) +{ + return xsm_ops->platform_op(op); +} + static inline int xsm_firmware_info (void) { return xsm_ops->firmware_info(); diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c index f6a0807..1e7f42c 100644 --- a/xen/xsm/dummy.c +++ b/xen/xsm/dummy.c @@ -144,6 +144,7 @@ void xsm_fixup_ops (struct xsm_operations *ops) set_to_dummy_if_null(ops, microcode); set_to_dummy_if_null(ops, physinfo); set_to_dummy_if_null(ops, platform_quirk); + set_to_dummy_if_null(ops, platform_op); set_to_dummy_if_null(ops, firmware_info); set_to_dummy_if_null(ops, efi_call); set_to_dummy_if_null(ops, acpi_sleep); diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index b3698c7..63f936b 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -1316,6 +1316,38 @@ static int flask_platform_quirk(uint32_t quirk) XEN__QUIRK, NULL); } +static int flask_platform_op(uint32_t op) +{ + switch ( op ) + { + case XENPF_settime: + case XENPF_add_memtype: + case XENPF_del_memtype: + case XENPF_read_memtype: + case XENPF_microcode_update: + case XENPF_platform_quirk: + case XENPF_firmware_info: + case XENPF_efi_runtime_call: + case XENPF_enter_acpi_sleep: + case XENPF_change_freq: + case XENPF_getidletime: + case XENPF_set_processor_pminfo: + case XENPF_get_cpuinfo: + case XENPF_get_cpu_version: + case XENPF_cpu_online: + case XENPF_cpu_offline: + case XENPF_cpu_hotadd: + case XENPF_mem_hotadd: + /* These operations have their own XSM hooks */ + return 0; + case XENPF_core_parking: + return domain_has_xen(current->domain, XEN__PM_OP); + default: + printk("flask_platform_op: Unknown op %d\n", op); + return -EPERM; + } +} + static int flask_firmware_info(void) { return domain_has_xen(current->domain, XEN__FIRMWARE); @@ -1687,6 +1719,7 @@ static struct xsm_operations flask_ops = { .microcode = flask_microcode, .physinfo = flask_physinfo, .platform_quirk = flask_platform_quirk, + .platform_op = flask_platform_op, .firmware_info = flask_firmware_info, .efi_call = flask_efi_call, .acpi_sleep = flask_acpi_sleep, -- 1.7.11.7
Daniel De Graaf
2013-Jan-10 15:33 UTC
[PATCH 09/22] xsm/flask: Add checks on the domain performing the set_target operation
The existing domain__set_target check only verifies that the source and target domains can be associated. We also need to check that the privileged domain making this association is allowed to do so. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> --- xen/xsm/flask/hooks.c | 7 +++++++ xen/xsm/flask/policy/access_vectors | 2 ++ 2 files changed, 9 insertions(+) diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index 63f936b..c2a1de0 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -577,6 +577,13 @@ static int flask_domain_settime(struct domain *d) static int flask_set_target(struct domain *d, struct domain *e) { + int rc; + rc = domain_has_perm(current->domain, d, SECCLASS_DOMAIN2, DOMAIN2__MAKE_PRIV_FOR); + if ( rc ) + return rc; + rc = domain_has_perm(current->domain, e, SECCLASS_DOMAIN2, DOMAIN2__SET_AS_TARGET); + if ( rc ) + return rc; return domain_has_perm(d, e, SECCLASS_DOMAIN, DOMAIN__SET_TARGET); } diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors index c7e29ab..11d02da 100644 --- a/xen/xsm/flask/policy/access_vectors +++ b/xen/xsm/flask/policy/access_vectors @@ -78,6 +78,8 @@ class domain2 relabelfrom relabelto relabelself + make_priv_for + set_as_target } class hvm -- 1.7.11.7
The FLASK module was missing implementations of some hooks and did not have access vectors defined for 10 domctls; define these now. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> --- tools/flask/policy/policy/modules/xen/xen.if | 4 +- xen/xsm/flask/hooks.c | 66 +++++++++++++++++++++++----- xen/xsm/flask/policy/access_vectors | 5 +++ 3 files changed, 63 insertions(+), 12 deletions(-) diff --git a/tools/flask/policy/policy/modules/xen/xen.if b/tools/flask/policy/policy/modules/xen/xen.if index 2ad11b2..59ba171 100644 --- a/tools/flask/policy/policy/modules/xen/xen.if +++ b/tools/flask/policy/policy/modules/xen/xen.if @@ -29,6 +29,7 @@ define(`create_domain_common'', ` getdomaininfo hypercall setvcpucontext setextvcpucontext scheduler getvcpuinfo getvcpuextstate getaddrsize getvcpuaffinity setvcpuaffinity }; + allow $1 $2:domain2 { set_cpuid settsc }; allow $1 $2:security check_context; allow $1 $2:shadow enable; allow $1 $2:mmu {map_read map_write adjust memorymap physmap pinpage}; @@ -67,6 +68,7 @@ define(`migrate_domain_out'', ` allow $1 $2:hvm { gethvmc getparam irqlevel }; allow $1 $2:mmu { stat pageinfo map_read }; allow $1 $2:domain { getaddrsize getvcpucontext getextvcpucontext getvcpuextstate pause destroy }; + allow $1 $2:domain2 gettsc; '') ################################################################################ @@ -112,7 +114,7 @@ define(`device_model'', ` domain_comms($1, $2) allow $1 $2:domain { set_target shutdown }; allow $1 $2:mmu { map_read map_write adjust physmap }; - allow $1 $2:hvm { getparam setparam trackdirtyvram hvmctl irqlevel pciroute }; + allow $1 $2:hvm { getparam setparam trackdirtyvram hvmctl irqlevel pciroute cacheattr send_irq }; '') ################################################################################ # diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index c2a1de0..fa62290 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -650,25 +650,32 @@ static int flask_domctl(struct domain *d, int cmd) #endif return 0; + case XEN_DOMCTL_debug_op: + case XEN_DOMCTL_gdbsx_guestmemio: + case XEN_DOMCTL_gdbsx_pausevcpu: + case XEN_DOMCTL_gdbsx_unpausevcpu: + case XEN_DOMCTL_gdbsx_domstatus: + return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, + DOMAIN__SETDEBUGGING); + case XEN_DOMCTL_subscribe: case XEN_DOMCTL_disable_migrate: + case XEN_DOMCTL_suppress_spurious_page_faults: return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__SET_MISC_INFO); case XEN_DOMCTL_set_cpuid: - case XEN_DOMCTL_suppress_spurious_page_faults: - case XEN_DOMCTL_debug_op: + return domain_has_perm(current->domain, d, SECCLASS_DOMAIN2, DOMAIN2__SET_CPUID); + case XEN_DOMCTL_gettscinfo: + return domain_has_perm(current->domain, d, SECCLASS_DOMAIN2, DOMAIN2__GETTSC); + case XEN_DOMCTL_settscinfo: + return domain_has_perm(current->domain, d, SECCLASS_DOMAIN2, DOMAIN2__SETTSC); + case XEN_DOMCTL_audit_p2m: - case XEN_DOMCTL_gdbsx_guestmemio: - case XEN_DOMCTL_gdbsx_pausevcpu: - case XEN_DOMCTL_gdbsx_unpausevcpu: - case XEN_DOMCTL_gdbsx_domstatus: - /* TODO add per-subfunction hooks */ - if ( !IS_PRIV(current->domain) ) - return -EPERM; - return 0; + return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__AUDIT_P2M); + default: printk("flask_domctl: Unknown op %d\n", cmd); return -EPERM; @@ -922,6 +929,11 @@ static int flask_iomem_permission(struct domain *d, uint64_t start, uint64_t end return security_iterate_iomem_sids(start, end, _iomem_has_perm, &data); } +static int flask_iomem_mapping(struct domain *d, uint64_t start, uint64_t end, uint8_t access) +{ + return flask_iomem_permission(d, start, end, access); +} + static int flask_pci_config_permission(struct domain *d, uint32_t machine_bdf, uint16_t start, uint16_t end, uint8_t access) { u32 rsid; @@ -1129,7 +1141,6 @@ static int _ioport_has_perm(void *v, u32 sid, unsigned long start, unsigned long return avc_has_perm(data->tsec->sid, sid, SECCLASS_RESOURCE, RESOURCE__USE, &ad); } - static int flask_ioport_permission(struct domain *d, uint32_t start, uint32_t end, uint8_t access) { int rc; @@ -1152,6 +1163,11 @@ static int flask_ioport_permission(struct domain *d, uint32_t start, uint32_t en return security_iterate_ioport_sids(start, end, _ioport_has_perm, &data); } +static int flask_ioport_mapping(struct domain *d, uint32_t start, uint32_t end, uint8_t access) +{ + return flask_ioport_permission(d, start, end, access); +} + static int flask_getpageframeinfo(struct domain *d) { return domain_has_perm(current->domain, d, SECCLASS_MMU, MMU__PAGEINFO); @@ -1210,6 +1226,25 @@ static int flask_address_size(struct domain *d, uint32_t cmd) return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, perm); } +static int flask_machine_address_size(struct domain *d, uint32_t cmd) +{ + u32 perm; + + switch ( cmd ) + { + case XEN_DOMCTL_set_machine_address_size: + perm = DOMAIN__SETADDRSIZE; + break; + case XEN_DOMCTL_get_machine_address_size: + perm = DOMAIN__GETADDRSIZE; + break; + default: + return -EPERM; + } + + return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, perm); +} + static int flask_hvm_param(struct domain *d, unsigned long op) { u32 perm; @@ -1247,6 +1282,11 @@ static int flask_hvm_set_pci_link_route(struct domain *d) return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__PCIROUTE); } +static int flask_hvm_inject_msi(struct domain *d) +{ + return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__SEND_IRQ); +} + static int flask_mem_event(struct domain *d) { return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__MEM_EVENT); @@ -1690,6 +1730,7 @@ static struct xsm_operations flask_ops = { .unmap_domain_pirq = flask_unmap_domain_pirq, .irq_permission = flask_irq_permission, .iomem_permission = flask_iomem_permission, + .iomem_mapping = flask_iomem_mapping, .pci_config_permission = flask_pci_config_permission, .resource_plug_core = flask_resource_plug_core, @@ -1714,10 +1755,12 @@ static struct xsm_operations flask_ops = { .hypercall_init = flask_hypercall_init, .hvmcontext = flask_hvmcontext, .address_size = flask_address_size, + .machine_address_size = flask_machine_address_size, .hvm_param = flask_hvm_param, .hvm_set_pci_intx_level = flask_hvm_set_pci_intx_level, .hvm_set_isa_irq_level = flask_hvm_set_isa_irq_level, .hvm_set_pci_link_route = flask_hvm_set_pci_link_route, + .hvm_inject_msi = flask_hvm_inject_msi, .mem_event = flask_mem_event, .mem_sharing = flask_mem_sharing, .apic = flask_apic, @@ -1750,6 +1793,7 @@ static struct xsm_operations flask_ops = { .ext_vcpucontext = flask_ext_vcpucontext, .vcpuextstate = flask_vcpuextstate, .ioport_permission = flask_ioport_permission, + .ioport_mapping = flask_ioport_mapping, #endif }; diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors index 11d02da..ea65e45 100644 --- a/xen/xsm/flask/policy/access_vectors +++ b/xen/xsm/flask/policy/access_vectors @@ -80,6 +80,9 @@ class domain2 relabelself make_priv_for set_as_target + set_cpuid + gettsc + settsc } class hvm @@ -97,6 +100,8 @@ class hvm hvmctl mem_event mem_sharing + audit_p2m + send_irq } class event -- 1.7.11.7
Daniel De Graaf
2013-Jan-10 15:33 UTC
[PATCH 11/22] xsm/flask: add distinct SIDs for self/target access
Because the FLASK XSM module no longer checks IS_PRIV for remote domain accesses covered by XSM permissions, domains now have the ability to perform memory management and other functions on all domains that have the same type. While it is possible to prevent this by only creating one domain per type, this solution significantly limits the flexibility of the type system. This patch introduces a domain type transition to represent a domain that is operating on itself. In the example policy, this is demonstrated by creating a type with _self appended when declaring a domain type which will be used for reflexive operations. AVCs for a domain of type domU_t will look like the following: scontext=system_u:system_r:domU_t tcontext=system_u:system_r:domU_t_self This change also allows policy to distinguish between event channels a domain creates to itself and event channels created between domains of the same type. The IS_PRIV_FOR check used for device model domains is also no longer checked by FLASK; a similar transition is performed when the target is set and used when the device model accesses its target domain. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> --- docs/misc/xsm-flask.txt | 43 ++- tools/flask/policy/policy/modules/xen/xen.if | 60 +++- tools/flask/policy/policy/modules/xen/xen.te | 13 +- xen/xsm/flask/flask_op.c | 9 + xen/xsm/flask/hooks.c | 422 +++++++++++++-------------- xen/xsm/flask/include/objsec.h | 2 + 6 files changed, 307 insertions(+), 242 deletions(-) diff --git a/docs/misc/xsm-flask.txt b/docs/misc/xsm-flask.txt index 0778a28..ff81b01 100644 --- a/docs/misc/xsm-flask.txt +++ b/docs/misc/xsm-flask.txt @@ -68,9 +68,43 @@ HVM domains with stubdomain device models use two types (one per domain): - dm_dom_t is the device model for a domain with type domHVM_t One disadvantage of using type enforcement to enforce isolation is that a new -type is needed for each group of domains. In addition, it is not possible to -allow isolated_domU_t cannot to create loopback event channels without allowing -two domains of type isolated_domU_t to communicate with one another. +type is needed for each group of domains. The user field can be used to address +this for the most common case of groups that can communicate internally but not +externally; see "Users and roles" below. + +Type transitions +---------------- + +Xen defines a number of operations such as memory mapping that are necessary for +a domain to perform on itself, but are also undesirable to allow a domain to +perform on every other domain of the same label. While it is possible to address +this by only creating one domain per type, this solution significantly limits +the flexibility of the type system. Another method to address this issue is to +duplicate the permission names for every operation that can be performed on the +current domain or on other domains; however, this significantly increases the +necessary number of permissions and complicates the XSM hooks. Instead, this is +addressed by allowing a distinct type to be used for a domain''s access to +itself. The same applies for a device model domain''s access to its designated +target, allowing the IS_PRIV_FOR checks used in Xen''s DAC model to be +implemented in FLASK. + +Upon domain creation (or relabel), a type transition is computed using the +domain''s label as the source and target. The result of this computation is used +as the target when the domain accesses itself. In the example policy, this +computed type is the result of appending _self to a domain''s type: domU_t_self +for domU_t. If no type transition rule exists, the domain will continue to use +its own label for both the source and target. An AVC message will look like: + + scontext=system_u:system_r:domU_t tcontext=system_u:system_r:domU_t_self + +A similar type transition is done when a device model domain is associated with +its target using the set_target operation. The transition is computed with the +target domain as the source and the device model domain as the target: this +ordering was chosen in order to preserve the original label for the target when +no type transition rule exists. In the example policy, these computed types are +the result of appending _target to the domain. + +Type transitions are also used to compute the labels of event channels. Users and roles --------------- @@ -84,7 +118,8 @@ the customer_1 user. Access control rules involving users and roles are defined in the policy constraints file (tools/flask/policy/policy/constraints). The example policy provides constraints that prevent different users from communicating using -grants or event channels, while still allowing communication with dom0. +grants or event channels, while still allowing communication with the system_u +user where dom0 resides. Resource Policy --------------- diff --git a/tools/flask/policy/policy/modules/xen/xen.if b/tools/flask/policy/policy/modules/xen/xen.if index 59ba171..d630f47 100644 --- a/tools/flask/policy/policy/modules/xen/xen.if +++ b/tools/flask/policy/policy/modules/xen/xen.if @@ -5,15 +5,34 @@ # Domain creation and setup # ################################################################################ +define(`declare_domain_common'', ` + allow $1 $2:grant { query setup }; + allow $1 $2:mmu { adjust physmap map_read map_write stat pinpage updatemp }; + allow $1 $2:hvm { getparam setparam }; +'') + # declare_domain(type, attrs...) -# Declare a type as a domain type, and allow basic domain setup +# Declare a domain type, along with associated _self and _channel types +# Allow the domain to perform basic operations on itself define(`declare_domain'', ` type $1, domain_type`''ifelse(`$#'', `1'', `'', `,shift($@)''); + type $1_self, domain_type, domain_self_type; + type_transition $1 $1:domain $1_self; + type $1_channel, event_type; + type_transition $1 domain_type:event $1_channel; + declare_domain_common($1, $1_self) +'') + +# declare_singleton_domain(type, attrs...) +# Declare a domain type and associated _channel types. +# Note: Because the domain can perform basic operations on itself and any +# other domain of the same type, this constructor should be used for types +# containing at most one domain. This is not enforced by policy. +define(`declare_singleton_domain'', ` + type $1, domain_type`''ifelse(`$#'', `1'', `'', `,shift($@)''); type $1_channel, event_type; type_transition $1 domain_type:event $1_channel; - allow $1 $1:grant { query setup }; - allow $1 $1:mmu { adjust physmap map_read map_write stat pinpage }; - allow $1 $1:hvm { getparam setparam }; + declare_domain_common($1, $1) '') # declare_build_label(type) @@ -51,6 +70,7 @@ define(`create_domain_build_label'', ` allow $1 $2_channel:event create; allow $1 $2_building:domain2 relabelfrom; allow $1 $2:domain2 relabelto; + allow $2_building $2:domain transition; '') # manage_domain(priv, target) @@ -101,20 +121,36 @@ define(`domain_comms'', ` '') # domain_self_comms(domain) -# Allow a domain types to communicate with others of its type using grants -# and event channels (this includes event channels to DOMID_SELF) +# Allow a non-singleton domain type to communicate with itself using grants +# and event channels define(`domain_self_comms'', ` - create_channel($1, $1, $1_channel) - allow $1 $1:grant { map_read map_write copy unmap }; + create_channel($1, $1_self, $1_channel) + allow $1 $1_self:grant { map_read map_write copy unmap }; '') # device_model(dm_dom, hvm_dom) # Define how a device model domain interacts with its target define(`device_model'', ` - domain_comms($1, $2) - allow $1 $2:domain { set_target shutdown }; - allow $1 $2:mmu { map_read map_write adjust physmap }; - allow $1 $2:hvm { getparam setparam trackdirtyvram hvmctl irqlevel pciroute cacheattr send_irq }; + type $2_target, domain_type, domain_target_type; + type_transition $2 $1:domain $2_target; + allow $1 $2:domain set_target; + + type_transition $2_target domain_type:event $2_channel; + create_channel($1, $2_target, $1_channel) + create_channel($2, $1, $2_channel) + allow $1 $2_channel:event create; + + allow $1 $2_target:domain shutdown; + allow $1 $2_target:mmu { map_read map_write adjust physmap }; + allow $1 $2_target:hvm { getparam setparam trackdirtyvram hvmctl irqlevel pciroute cacheattr send_irq }; +'') + +# make_device_model(priv, dm_dom, hvm_dom) +# Allow creation of a device model and HVM domain pair +define(`make_device_model'', ` + device_model($2, $3) + allow $1 $2:domain2 make_priv_for; + allow $1 $3:domain2 set_as_target; '') ################################################################################ # diff --git a/tools/flask/policy/policy/modules/xen/xen.te b/tools/flask/policy/policy/modules/xen/xen.te index 1162153..8d33285 100644 --- a/tools/flask/policy/policy/modules/xen/xen.te +++ b/tools/flask/policy/policy/modules/xen/xen.te @@ -8,6 +8,8 @@ ################################################################################ attribute xen_type; attribute domain_type; +attribute domain_self_type; +attribute domain_target_type; attribute resource_type; attribute event_type; attribute mls_priv; @@ -25,7 +27,7 @@ attribute mls_priv; type xen_t, xen_type, mls_priv; # Domain 0 -declare_domain(dom0_t, mls_priv); +declare_singleton_domain(dom0_t, mls_priv); # Untracked I/O memory (pseudo-domain) type domio_t, xen_type; @@ -69,7 +71,7 @@ admin_device(dom0_t, ioport_t) admin_device(dom0_t, iomem_t) allow dom0_t domio_t:mmu { map_read map_write }; -domain_self_comms(dom0_t) +domain_comms(dom0_t, dom0_t) auditallow dom0_t security_t:security { load_policy setenforce setbool }; @@ -84,11 +86,14 @@ domain_self_comms(domU_t) create_domain(dom0_t, domU_t) manage_domain(dom0_t, domU_t) domain_comms(dom0_t, domU_t) +domain_comms(domU_t, domU_t) +domain_self_comms(domU_t) declare_domain(isolated_domU_t) create_domain(dom0_t, isolated_domU_t) manage_domain(dom0_t, isolated_domU_t) domain_comms(dom0_t, isolated_domU_t) +domain_self_comms(isolated_domU_t) # Declare a boolean that denies creation of prot_domU_t domains gen_bool(prot_doms_locked, false) @@ -98,6 +103,8 @@ if (!prot_doms_locked) { } domain_comms(dom0_t, prot_domU_t) domain_comms(domU_t, prot_domU_t) +domain_comms(prot_domU_t, prot_domU_t) +domain_self_comms(prot_domU_t) # domHVM_t is meant to be paired with a qemu-dm stub domain of type dm_dom_t declare_domain(domHVM_t) @@ -110,7 +117,7 @@ declare_domain(dm_dom_t) create_domain(dom0_t, dm_dom_t) manage_domain(dom0_t, dm_dom_t) domain_comms(dom0_t, dm_dom_t) -device_model(dm_dom_t, domHVM_t) +make_device_model(dom0_t, dm_dom_t, domHVM_t) # nomigrate_t must be built via the nomigrate_t_building label; once built, # dom0 cannot read its memory. diff --git a/xen/xsm/flask/flask_op.c b/xen/xsm/flask/flask_op.c index a5d7748..4426ab9 100644 --- a/xen/xsm/flask/flask_op.c +++ b/xen/xsm/flask/flask_op.c @@ -612,6 +612,15 @@ static int flask_relabel_domain(struct xen_flask_relabel *arg) goto out; dsec->sid = arg->sid; + dsec->self_sid = arg->sid; + security_transition_sid(dsec->sid, dsec->sid, SECCLASS_DOMAIN, + &dsec->self_sid); + if ( d->target ) + { + struct domain_security_struct *tsec = d->target->ssid; + security_transition_sid(tsec->sid, dsec->sid, SECCLASS_DOMAIN, + &dsec->target_sid); + } out: rcu_unlock_domain(d); diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index fa62290..eaf9650 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -33,38 +33,69 @@ struct xsm_operations *original_ops = NULL; +static u32 domain_sid(struct domain *dom) +{ + struct domain_security_struct *dsec = dom->ssid; + return dsec->sid; +} + +static u32 domain_target_sid(struct domain *src, struct domain *dst) +{ + struct domain_security_struct *ssec = src->ssid; + struct domain_security_struct *dsec = dst->ssid; + if (src == dst) + return ssec->self_sid; + if (src->target == dst) + return ssec->target_sid; + return dsec->sid; +} + +static u32 evtchn_sid(const struct evtchn *chn) +{ + struct evtchn_security_struct *esec = chn->ssid; + return esec->sid; +} + static int domain_has_perm(struct domain *dom1, struct domain *dom2, u16 class, u32 perms) { - struct domain_security_struct *dsec1, *dsec2; + u32 ssid, tsid; struct avc_audit_data ad; AVC_AUDIT_DATA_INIT(&ad, NONE); ad.sdom = dom1; ad.tdom = dom2; - dsec1 = dom1->ssid; - dsec2 = dom2->ssid; + ssid = domain_sid(dom1); + tsid = domain_target_sid(dom1, dom2); - return avc_has_perm(dsec1->sid, dsec2->sid, class, perms, &ad); + return avc_has_perm(ssid, tsid, class, perms, &ad); } -static int domain_has_evtchn(struct domain *d, struct evtchn *chn, u32 perms) +static int avc_current_has_perm(u32 tsid, u16 class, u32 perm, + struct avc_audit_data *ad) { - struct domain_security_struct *dsec; - struct evtchn_security_struct *esec; + u32 csid = domain_sid(current->domain); + return avc_has_perm(csid, tsid, class, perm, ad); +} - dsec = d->ssid; - esec = chn->ssid; +static int current_has_perm(struct domain *d, u16 class, u32 perms) +{ + return domain_has_perm(current->domain, d, class, perms); +} - return avc_has_perm(dsec->sid, esec->sid, SECCLASS_EVENT, perms, NULL); +static int domain_has_evtchn(struct domain *d, struct evtchn *chn, u32 perms) +{ + u32 dsid = domain_sid(d); + u32 esid = evtchn_sid(chn); + + return avc_has_perm(dsid, esid, SECCLASS_EVENT, perms, NULL); } static int domain_has_xen(struct domain *d, u32 perms) { - struct domain_security_struct *dsec; - dsec = d->ssid; + u32 dsid = domain_sid(d); - return avc_has_perm(dsec->sid, SECINITSID_XEN, SECCLASS_XEN, perms, NULL); + return avc_has_perm(dsid, SECINITSID_XEN, SECCLASS_XEN, perms, NULL); } static int get_irq_sid(int irq, u32 *sid, struct avc_audit_data *ad) @@ -123,6 +154,7 @@ static int flask_domain_alloc_security(struct domain *d) dsec->sid = SECINITSID_UNLABELED; } + dsec->self_sid = dsec->sid; d->ssid = dsec; return 0; @@ -142,68 +174,55 @@ static void flask_domain_free_security(struct domain *d) static int flask_evtchn_unbound(struct domain *d1, struct evtchn *chn, domid_t id2) { - u32 newsid; + u32 sid1, sid2, newsid; int rc; - domid_t id; struct domain *d2; - struct domain_security_struct *dsec, *dsec1, *dsec2; struct evtchn_security_struct *esec; - dsec = current->domain->ssid; - dsec1 = d1->ssid; - esec = chn->ssid; - - if ( id2 == DOMID_SELF ) - id = current->domain->domain_id; - else - id = id2; - - d2 = get_domain_by_id(id); + d2 = rcu_lock_domain_by_any_id(id2); if ( d2 == NULL ) return -EPERM; - dsec2 = d2->ssid; - rc = security_transition_sid(dsec1->sid, dsec2->sid, SECCLASS_EVENT, - &newsid); + sid1 = domain_sid(d1); + sid2 = domain_target_sid(d1, d2); + esec = chn->ssid; + + rc = security_transition_sid(sid1, sid2, SECCLASS_EVENT, &newsid); if ( rc ) goto out; - rc = avc_has_perm(dsec->sid, newsid, SECCLASS_EVENT, EVENT__CREATE, NULL); + rc = avc_current_has_perm(newsid, SECCLASS_EVENT, EVENT__CREATE, NULL); if ( rc ) goto out; - rc = avc_has_perm(newsid, dsec2->sid, SECCLASS_EVENT, EVENT__BIND, NULL); + rc = avc_has_perm(newsid, sid2, SECCLASS_EVENT, EVENT__BIND, NULL); if ( rc ) goto out; - else - esec->sid = newsid; + + esec->sid = newsid; out: - put_domain(d2); + rcu_unlock_domain(d2); return rc; } static int flask_evtchn_interdomain(struct domain *d1, struct evtchn *chn1, struct domain *d2, struct evtchn *chn2) { - u32 newsid; + u32 sid1, sid2, newsid, reverse_sid; int rc; - struct domain_security_struct *dsec, *dsec1, *dsec2; - struct evtchn_security_struct *esec1, *esec2; + struct evtchn_security_struct *esec1; struct avc_audit_data ad; AVC_AUDIT_DATA_INIT(&ad, NONE); ad.sdom = d1; ad.tdom = d2; - dsec = current->domain->ssid; - dsec1 = d1->ssid; - dsec2 = d2->ssid; + sid1 = domain_sid(d1); + sid2 = domain_target_sid(d1, d2); esec1 = chn1->ssid; - esec2 = chn2->ssid; - rc = security_transition_sid(dsec1->sid, dsec2->sid, - SECCLASS_EVENT, &newsid); + rc = security_transition_sid(sid1, sid2, SECCLASS_EVENT, &newsid); if ( rc ) { printk("%s: security_transition_sid failed, rc=%d (domain=%d)\n", @@ -211,15 +230,20 @@ static int flask_evtchn_interdomain(struct domain *d1, struct evtchn *chn1, return rc; } - rc = avc_has_perm(dsec->sid, newsid, SECCLASS_EVENT, EVENT__CREATE, &ad); + rc = avc_current_has_perm(newsid, SECCLASS_EVENT, EVENT__CREATE, &ad); if ( rc ) return rc; - rc = avc_has_perm(newsid, dsec2->sid, SECCLASS_EVENT, EVENT__BIND, &ad); + rc = avc_has_perm(newsid, sid2, SECCLASS_EVENT, EVENT__BIND, &ad); if ( rc ) return rc; - rc = avc_has_perm(esec2->sid, dsec1->sid, SECCLASS_EVENT, EVENT__BIND, &ad); + /* It''s possible the target domain has changed (relabel or destroy/create) + * since the unbound part was created; re-validate this binding now. + */ + reverse_sid = evtchn_sid(chn2); + sid1 = domain_target_sid(d2, d1); + rc = avc_has_perm(reverse_sid, sid1, SECCLASS_EVENT, EVENT__BIND, &ad); if ( rc ) return rc; @@ -302,7 +326,6 @@ static void flask_free_security_evtchn(struct evtchn *chn) static char *flask_show_security_evtchn(struct domain *d, const struct evtchn *chn) { - struct evtchn_security_struct *esec; int irq; u32 sid = 0; char *ctx; @@ -312,9 +335,7 @@ static char *flask_show_security_evtchn(struct domain *d, const struct evtchn *c { case ECS_UNBOUND: case ECS_INTERDOMAIN: - esec = chn->ssid; - if ( esec ) - sid = esec->sid; + sid = evtchn_sid(chn); break; case ECS_PIRQ: irq = domain_pirq_to_irq(d, chn->u.pirq.irq); @@ -367,12 +388,12 @@ static int flask_grant_query_size(struct domain *d1, struct domain *d2) static int flask_get_pod_target(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__GETPODTARGET); + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETPODTARGET); } static int flask_set_pod_target(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__SETPODTARGET); + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETPODTARGET); } static int flask_memory_adjust_reservation(struct domain *d1, struct domain *d2) @@ -455,70 +476,65 @@ static int flask_schedop_shutdown(struct domain *d1, struct domain *d2) static void flask_security_domaininfo(struct domain *d, struct xen_domctl_getdomaininfo *info) { - struct domain_security_struct *dsec; - - dsec = d->ssid; - info->ssidref = dsec->sid; + info->ssidref = domain_sid(d); } static int flask_setvcpucontext(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, - DOMAIN__SETVCPUCONTEXT); + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETVCPUCONTEXT); } static int flask_pausedomain(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__PAUSE); + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__PAUSE); } static int flask_unpausedomain(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__UNPAUSE); + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__UNPAUSE); } static int flask_resumedomain(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__RESUME); + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__RESUME); } static int flask_domain_create(struct domain *d, u32 ssidref) { int rc; - struct domain_security_struct *dsec1; - struct domain_security_struct *dsec2; + struct domain_security_struct *dsec = d->ssid; static int dom0_created = 0; - dsec1 = current->domain->ssid; - dsec2 = d->ssid; - if ( is_idle_domain(current->domain) && !dom0_created ) { - dsec2->sid = SECINITSID_DOM0; + dsec->sid = SECINITSID_DOM0; dom0_created = 1; - return 0; } + else + { + rc = avc_current_has_perm(ssidref, SECCLASS_DOMAIN, + DOMAIN__CREATE, NULL); + if ( rc ) + return rc; - rc = avc_has_perm(dsec1->sid, ssidref, SECCLASS_DOMAIN, - DOMAIN__CREATE, NULL); - if ( rc ) - return rc; + dsec->sid = ssidref; + } + dsec->self_sid = dsec->sid; - dsec2->sid = ssidref; + rc = security_transition_sid(dsec->sid, dsec->sid, SECCLASS_DOMAIN, + &dsec->self_sid); return rc; } static int flask_max_vcpus(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, - DOMAIN__MAX_VCPUS); + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__MAX_VCPUS); } static int flask_destroydomain(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, - DOMAIN__DESTROY); + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__DESTROY); } static int flask_vcpuaffinity(int cmd, struct domain *d) @@ -537,7 +553,7 @@ static int flask_vcpuaffinity(int cmd, struct domain *d) return -EPERM; } - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, perm ); + return current_has_perm(d, SECCLASS_DOMAIN, perm ); } static int flask_scheduler(struct domain *d) @@ -548,43 +564,51 @@ static int flask_scheduler(struct domain *d) if ( rc ) return rc; - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, - DOMAIN__SCHEDULER); + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SCHEDULER); } static int flask_getdomaininfo(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, - DOMAIN__GETDOMAININFO); + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETDOMAININFO); } static int flask_getvcpucontext(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, - DOMAIN__GETVCPUCONTEXT); + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETVCPUCONTEXT); } static int flask_getvcpuinfo(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, - DOMAIN__GETVCPUINFO); + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETVCPUINFO); } static int flask_domain_settime(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__SETTIME); + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETTIME); } -static int flask_set_target(struct domain *d, struct domain *e) +static int flask_set_target(struct domain *d, struct domain *t) { int rc; - rc = domain_has_perm(current->domain, d, SECCLASS_DOMAIN2, DOMAIN2__MAKE_PRIV_FOR); + struct domain_security_struct *dsec, *tsec; + dsec = d->ssid; + tsec = t->ssid; + + rc = current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__MAKE_PRIV_FOR); if ( rc ) return rc; - rc = domain_has_perm(current->domain, e, SECCLASS_DOMAIN2, DOMAIN2__SET_AS_TARGET); + rc = current_has_perm(t, SECCLASS_DOMAIN2, DOMAIN2__SET_AS_TARGET); if ( rc ) return rc; - return domain_has_perm(d, e, SECCLASS_DOMAIN, DOMAIN__SET_TARGET); + /* Use avc_has_perm to avoid resolving target/current SID */ + rc = avc_has_perm(dsec->sid, tsec->sid, SECCLASS_DOMAIN, DOMAIN__SET_TARGET, NULL); + if ( rc ) + return rc; + + /* (tsec, dsec) defaults the label to tsec, as it should here */ + rc = security_transition_sid(tsec->sid, dsec->sid, SECCLASS_DOMAIN, + &dsec->target_sid); + return rc; } static int flask_domctl(struct domain *d, int cmd) @@ -655,26 +679,24 @@ static int flask_domctl(struct domain *d, int cmd) case XEN_DOMCTL_gdbsx_pausevcpu: case XEN_DOMCTL_gdbsx_unpausevcpu: case XEN_DOMCTL_gdbsx_domstatus: - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, - DOMAIN__SETDEBUGGING); + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETDEBUGGING); case XEN_DOMCTL_subscribe: case XEN_DOMCTL_disable_migrate: case XEN_DOMCTL_suppress_spurious_page_faults: - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, - DOMAIN__SET_MISC_INFO); + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SET_MISC_INFO); case XEN_DOMCTL_set_cpuid: - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN2, DOMAIN2__SET_CPUID); + return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__SET_CPUID); case XEN_DOMCTL_gettscinfo: - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN2, DOMAIN2__GETTSC); + return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__GETTSC); case XEN_DOMCTL_settscinfo: - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN2, DOMAIN2__SETTSC); + return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__SETTSC); case XEN_DOMCTL_audit_p2m: - return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__AUDIT_P2M); + return current_has_perm(d, SECCLASS_HVM, HVM__AUDIT_P2M); default: printk("flask_domctl: Unknown op %d\n", cmd); @@ -716,7 +738,7 @@ static int flask_sysctl(int cmd) static int flask_set_virq_handler(struct domain *d, uint32_t virq) { - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__SET_VIRQ_HANDLER); + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SET_VIRQ_HANDLER); } static int flask_tbufcontrol(void) @@ -741,20 +763,17 @@ static int flask_sched_id(void) static int flask_setdomainmaxmem(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, - DOMAIN__SETDOMAINMAXMEM); + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETDOMAINMAXMEM); } static int flask_setdomainhandle(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, - DOMAIN__SETDOMAINHANDLE); + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETDOMAINHANDLE); } static int flask_setdebugging(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, - DOMAIN__SETDEBUGGING); + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETDEBUGGING); } static int flask_debug_keys(void) @@ -816,14 +835,12 @@ static char *flask_show_irq_sid (int irq) static int flask_map_domain_pirq (struct domain *d, int irq, void *data) { - u32 sid; + u32 sid, dsid; int rc = -EPERM; struct msi_info *msi = data; - - struct domain_security_struct *ssec, *tsec; struct avc_audit_data ad; - rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE, RESOURCE__ADD); + rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__ADD); if ( rc ) return rc; @@ -839,14 +856,13 @@ static int flask_map_domain_pirq (struct domain *d, int irq, void *data) if ( rc ) return rc; - ssec = current->domain->ssid; - tsec = d->ssid; + dsid = domain_sid(d); - rc = avc_has_perm(ssec->sid, sid, SECCLASS_RESOURCE, RESOURCE__ADD_IRQ, &ad); + rc = avc_current_has_perm(sid, SECCLASS_RESOURCE, RESOURCE__ADD_IRQ, &ad); if ( rc ) return rc; - rc = avc_has_perm(tsec->sid, sid, SECCLASS_RESOURCE, RESOURCE__USE, &ad); + rc = avc_has_perm(dsid, sid, SECCLASS_RESOURCE, RESOURCE__USE, &ad); return rc; } @@ -854,16 +870,12 @@ static int flask_unmap_domain_pirq (struct domain *d, int irq) { u32 sid; int rc = -EPERM; - - struct domain_security_struct *ssec; struct avc_audit_data ad; - rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE, RESOURCE__REMOVE); + rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__REMOVE); if ( rc ) return rc; - ssec = current->domain->ssid; - if ( irq < nr_static_irqs ) { rc = get_irq_sid(irq, &sid, &ad); } else { @@ -874,19 +886,19 @@ static int flask_unmap_domain_pirq (struct domain *d, int irq) if ( rc ) return rc; - rc = avc_has_perm(ssec->sid, sid, SECCLASS_RESOURCE, RESOURCE__REMOVE_IRQ, &ad); + rc = avc_current_has_perm(sid, SECCLASS_RESOURCE, RESOURCE__REMOVE_IRQ, &ad); return rc; } static int flask_irq_permission (struct domain *d, int pirq, uint8_t access) { /* the PIRQ number is not useful; real IRQ is checked during mapping */ - return domain_has_perm(current->domain, d, SECCLASS_RESOURCE, - resource_to_perm(access)); + return current_has_perm(d, SECCLASS_RESOURCE, resource_to_perm(access)); } struct iomem_has_perm_data { - struct domain_security_struct *ssec, *tsec; + u32 ssid; + u32 dsid; u32 perm; }; @@ -900,12 +912,12 @@ static int _iomem_has_perm(void *v, u32 sid, unsigned long start, unsigned long ad.range.start = start; ad.range.end = end; - rc = avc_has_perm(data->ssec->sid, sid, SECCLASS_RESOURCE, data->perm, &ad); + rc = avc_has_perm(data->ssid, sid, SECCLASS_RESOURCE, data->perm, &ad); if ( rc ) return rc; - return avc_has_perm(data->tsec->sid, sid, SECCLASS_RESOURCE, RESOURCE__USE, &ad); + return avc_has_perm(data->dsid, sid, SECCLASS_RESOURCE, RESOURCE__USE, &ad); } static int flask_iomem_permission(struct domain *d, uint64_t start, uint64_t end, uint8_t access) @@ -913,7 +925,7 @@ static int flask_iomem_permission(struct domain *d, uint64_t start, uint64_t end struct iomem_has_perm_data data; int rc; - rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE, + rc = current_has_perm(d, SECCLASS_RESOURCE, resource_to_perm(access)); if ( rc ) return rc; @@ -923,8 +935,8 @@ static int flask_iomem_permission(struct domain *d, uint64_t start, uint64_t end else data.perm = RESOURCE__REMOVE_IOMEM; - data.ssec = current->domain->ssid; - data.tsec = d->ssid; + data.ssid = domain_sid(current->domain); + data.dsid = domain_sid(d); return security_iterate_iomem_sids(start, end, _iomem_has_perm, &data); } @@ -936,10 +948,9 @@ static int flask_iomem_mapping(struct domain *d, uint64_t start, uint64_t end, u static int flask_pci_config_permission(struct domain *d, uint32_t machine_bdf, uint16_t start, uint16_t end, uint8_t access) { - u32 rsid; + u32 dsid, rsid; int rc = -EPERM; struct avc_audit_data ad; - struct domain_security_struct *ssec; u32 perm = RESOURCE__USE; rc = security_device_sid(machine_bdf, &rsid); @@ -952,33 +963,24 @@ static int flask_pci_config_permission(struct domain *d, uint32_t machine_bdf, u AVC_AUDIT_DATA_INIT(&ad, DEV); ad.device = (unsigned long) machine_bdf; - ssec = d->ssid; - return avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, perm, &ad); + dsid = domain_sid(d); + return avc_has_perm(dsid, rsid, SECCLASS_RESOURCE, perm, &ad); } static int flask_resource_plug_core(void) { - struct domain_security_struct *ssec; - - ssec = current->domain->ssid; - return avc_has_perm(ssec->sid, SECINITSID_DOMXEN, SECCLASS_RESOURCE, RESOURCE__PLUG, NULL); + return avc_current_has_perm(SECINITSID_DOMXEN, SECCLASS_RESOURCE, RESOURCE__PLUG, NULL); } static int flask_resource_unplug_core(void) { - struct domain_security_struct *ssec; - - ssec = current->domain->ssid; - return avc_has_perm(ssec->sid, SECINITSID_DOMXEN, SECCLASS_RESOURCE, RESOURCE__UNPLUG, NULL); + return avc_current_has_perm(SECINITSID_DOMXEN, SECCLASS_RESOURCE, RESOURCE__UNPLUG, NULL); } static int flask_resource_use_core(void) { - struct domain_security_struct *ssec; - - ssec = current->domain->ssid; - return avc_has_perm(ssec->sid, SECINITSID_DOMXEN, SECCLASS_RESOURCE, RESOURCE__USE, NULL); + return avc_current_has_perm(SECINITSID_DOMXEN, SECCLASS_RESOURCE, RESOURCE__USE, NULL); } static int flask_resource_plug_pci(uint32_t machine_bdf) @@ -986,7 +988,6 @@ static int flask_resource_plug_pci(uint32_t machine_bdf) u32 rsid; int rc = -EPERM; struct avc_audit_data ad; - struct domain_security_struct *ssec; rc = security_device_sid(machine_bdf, &rsid); if ( rc ) @@ -994,8 +995,7 @@ static int flask_resource_plug_pci(uint32_t machine_bdf) AVC_AUDIT_DATA_INIT(&ad, DEV); ad.device = (unsigned long) machine_bdf; - ssec = current->domain->ssid; - return avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__PLUG, &ad); + return avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__PLUG, &ad); } static int flask_resource_unplug_pci(uint32_t machine_bdf) @@ -1003,7 +1003,6 @@ static int flask_resource_unplug_pci(uint32_t machine_bdf) u32 rsid; int rc = -EPERM; struct avc_audit_data ad; - struct domain_security_struct *ssec; rc = security_device_sid(machine_bdf, &rsid); if ( rc ) @@ -1011,8 +1010,7 @@ static int flask_resource_unplug_pci(uint32_t machine_bdf) AVC_AUDIT_DATA_INIT(&ad, DEV); ad.device = (unsigned long) machine_bdf; - ssec = current->domain->ssid; - return avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__UNPLUG, &ad); + return avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__UNPLUG, &ad); } static int flask_resource_setup_pci(uint32_t machine_bdf) @@ -1020,7 +1018,6 @@ static int flask_resource_setup_pci(uint32_t machine_bdf) u32 rsid; int rc = -EPERM; struct avc_audit_data ad; - struct domain_security_struct *ssec; rc = security_device_sid(machine_bdf, &rsid); if ( rc ) @@ -1028,8 +1025,7 @@ static int flask_resource_setup_pci(uint32_t machine_bdf) AVC_AUDIT_DATA_INIT(&ad, DEV); ad.device = (unsigned long) machine_bdf; - ssec = current->domain->ssid; - return avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__SETUP, &ad); + return avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__SETUP, &ad); } static int flask_resource_setup_gsi(int gsi) @@ -1037,22 +1033,17 @@ static int flask_resource_setup_gsi(int gsi) u32 rsid; int rc = -EPERM; struct avc_audit_data ad; - struct domain_security_struct *ssec; rc = get_irq_sid(gsi, &rsid, &ad); if ( rc ) return rc; - ssec = current->domain->ssid; - return avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__SETUP, &ad); + return avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__SETUP, &ad); } static int flask_resource_setup_misc(void) { - struct domain_security_struct *ssec; - - ssec = current->domain->ssid; - return avc_has_perm(ssec->sid, SECINITSID_XEN, SECCLASS_RESOURCE, RESOURCE__SETUP, NULL); + return avc_current_has_perm(SECINITSID_XEN, SECCLASS_RESOURCE, RESOURCE__SETUP, NULL); } static inline int flask_page_offline(uint32_t cmd) @@ -1115,11 +1106,12 @@ static int flask_shadow_control(struct domain *d, uint32_t op) return -EPERM; } - return domain_has_perm(current->domain, d, SECCLASS_SHADOW, perm); + return current_has_perm(d, SECCLASS_SHADOW, perm); } struct ioport_has_perm_data { - struct domain_security_struct *ssec, *tsec; + u32 ssid; + u32 dsid; u32 perm; }; @@ -1133,12 +1125,12 @@ static int _ioport_has_perm(void *v, u32 sid, unsigned long start, unsigned long ad.range.start = start; ad.range.end = end; - rc = avc_has_perm(data->ssec->sid, sid, SECCLASS_RESOURCE, data->perm, &ad); + rc = avc_has_perm(data->ssid, sid, SECCLASS_RESOURCE, data->perm, &ad); if ( rc ) return rc; - return avc_has_perm(data->tsec->sid, sid, SECCLASS_RESOURCE, RESOURCE__USE, &ad); + return avc_has_perm(data->dsid, sid, SECCLASS_RESOURCE, RESOURCE__USE, &ad); } static int flask_ioport_permission(struct domain *d, uint32_t start, uint32_t end, uint8_t access) @@ -1146,7 +1138,7 @@ static int flask_ioport_permission(struct domain *d, uint32_t start, uint32_t en int rc; struct ioport_has_perm_data data; - rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE, + rc = current_has_perm(d, SECCLASS_RESOURCE, resource_to_perm(access)); if ( rc ) @@ -1157,8 +1149,8 @@ static int flask_ioport_permission(struct domain *d, uint32_t start, uint32_t en else data.perm = RESOURCE__REMOVE_IOPORT; - data.ssec = current->domain->ssid; - data.tsec = d->ssid; + data.ssid = domain_sid(current->domain); + data.dsid = domain_sid(d); return security_iterate_ioport_sids(start, end, _ioport_has_perm, &data); } @@ -1170,18 +1162,17 @@ static int flask_ioport_mapping(struct domain *d, uint32_t start, uint32_t end, static int flask_getpageframeinfo(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_MMU, MMU__PAGEINFO); + return current_has_perm(d, SECCLASS_MMU, MMU__PAGEINFO); } static int flask_getmemlist(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_MMU, MMU__PAGELIST); + return current_has_perm(d, SECCLASS_MMU, MMU__PAGELIST); } static int flask_hypercall_init(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, - DOMAIN__HYPERCALL); + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__HYPERCALL); } static int flask_hvmcontext(struct domain *d, uint32_t cmd) @@ -1204,7 +1195,7 @@ static int flask_hvmcontext(struct domain *d, uint32_t cmd) return -EPERM; } - return domain_has_perm(current->domain, d, SECCLASS_HVM, perm); + return current_has_perm(d, SECCLASS_HVM, perm); } static int flask_address_size(struct domain *d, uint32_t cmd) @@ -1223,7 +1214,7 @@ static int flask_address_size(struct domain *d, uint32_t cmd) return -EPERM; } - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, perm); + return current_has_perm(d, SECCLASS_DOMAIN, perm); } static int flask_machine_address_size(struct domain *d, uint32_t cmd) @@ -1264,37 +1255,37 @@ static int flask_hvm_param(struct domain *d, unsigned long op) perm = HVM__HVMCTL; } - return domain_has_perm(current->domain, d, SECCLASS_HVM, perm); + return current_has_perm(d, SECCLASS_HVM, perm); } static int flask_hvm_set_pci_intx_level(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__PCILEVEL); + return current_has_perm(d, SECCLASS_HVM, HVM__PCILEVEL); } static int flask_hvm_set_isa_irq_level(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__IRQLEVEL); + return current_has_perm(d, SECCLASS_HVM, HVM__IRQLEVEL); } static int flask_hvm_set_pci_link_route(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__PCIROUTE); + return current_has_perm(d, SECCLASS_HVM, HVM__PCIROUTE); } static int flask_hvm_inject_msi(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__SEND_IRQ); + return current_has_perm(d, SECCLASS_HVM, HVM__SEND_IRQ); } static int flask_mem_event(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__MEM_EVENT); + return current_has_perm(d, SECCLASS_HVM, HVM__MEM_EVENT); } static int flask_mem_sharing(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__MEM_SHARING); + return current_has_perm(d, SECCLASS_HVM, HVM__MEM_SHARING); } static int flask_apic(struct domain *d, int cmd) @@ -1356,11 +1347,7 @@ static int flask_physinfo(void) static int flask_platform_quirk(uint32_t quirk) { - struct domain_security_struct *dsec; - dsec = current->domain->ssid; - - return avc_has_perm(dsec->sid, SECINITSID_XEN, SECCLASS_XEN, - XEN__QUIRK, NULL); + return avc_current_has_perm(SECINITSID_XEN, SECCLASS_XEN, XEN__QUIRK, NULL); } static int flask_platform_op(uint32_t op) @@ -1422,16 +1409,12 @@ static int flask_getidletime(void) static int flask_machine_memory_map(void) { - struct domain_security_struct *dsec; - dsec = current->domain->ssid; - - return avc_has_perm(dsec->sid, SECINITSID_XEN, SECCLASS_MMU, - MMU__MEMORYMAP, NULL); + return avc_current_has_perm(SECINITSID_XEN, SECCLASS_MMU, MMU__MEMORYMAP, NULL); } static int flask_domain_memory_map(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_MMU, MMU__MEMORYMAP); + return current_has_perm(d, SECCLASS_MMU, MMU__MEMORYMAP); } static int domain_memory_perm(struct domain *d, struct domain *f, l1_pgentry_t pte) @@ -1454,17 +1437,17 @@ static int domain_memory_perm(struct domain *d, struct domain *f, l1_pgentry_t p if ( f->domain_id == DOMID_IO || !mfn_valid(fmfn) ) { struct avc_audit_data ad; - struct domain_security_struct *dsec = d->ssid; - u32 fsid; + u32 dsid, fsid; + rc = security_iomem_sid(fmfn, &fsid); + if ( rc ) + return rc; AVC_AUDIT_DATA_INIT(&ad, MEMORY); ad.sdom = d; ad.tdom = f; ad.memory.pte = pte.l1; ad.memory.mfn = fmfn; - rc = security_iomem_sid(fmfn, &fsid); - if ( rc ) - return rc; - return avc_has_perm(dsec->sid, fsid, SECCLASS_MMU, map_perms, &ad); + dsid = domain_sid(d); + return avc_has_perm(dsid, fsid, SECCLASS_MMU, map_perms, &ad); } return domain_has_perm(d, f, SECCLASS_MMU, map_perms); @@ -1507,43 +1490,40 @@ static int flask_remove_from_physmap(struct domain *d1, struct domain *d2) static int flask_sendtrigger(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__TRIGGER); + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__TRIGGER); } static int flask_get_device_group(uint32_t machine_bdf) { u32 rsid; int rc = -EPERM; - struct domain_security_struct *ssec = current->domain->ssid; rc = security_device_sid(machine_bdf, &rsid); if ( rc ) return rc; - return avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__STAT_DEVICE, NULL); + return avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__STAT_DEVICE, NULL); } static int flask_test_assign_device(uint32_t machine_bdf) { u32 rsid; int rc = -EPERM; - struct domain_security_struct *ssec = current->domain->ssid; rc = security_device_sid(machine_bdf, &rsid); if ( rc ) return rc; - return rc = avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__STAT_DEVICE, NULL); + return avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__STAT_DEVICE, NULL); } static int flask_assign_device(struct domain *d, uint32_t machine_bdf) { - u32 rsid; + u32 dsid, rsid; int rc = -EPERM; - struct domain_security_struct *ssec, *tsec; struct avc_audit_data ad; - rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE, RESOURCE__ADD); + rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__ADD); if ( rc ) return rc; @@ -1553,22 +1533,20 @@ static int flask_assign_device(struct domain *d, uint32_t machine_bdf) AVC_AUDIT_DATA_INIT(&ad, DEV); ad.device = (unsigned long) machine_bdf; - ssec = current->domain->ssid; - rc = avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__ADD_DEVICE, &ad); + rc = avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__ADD_DEVICE, &ad); if ( rc ) return rc; - tsec = d->ssid; - return avc_has_perm(tsec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__USE, &ad); + dsid = domain_sid(d); + return avc_has_perm(dsid, rsid, SECCLASS_RESOURCE, RESOURCE__USE, &ad); } static int flask_deassign_device(struct domain *d, uint32_t machine_bdf) { u32 rsid; int rc = -EPERM; - struct domain_security_struct *ssec = current->domain->ssid; - rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE, RESOURCE__REMOVE); + rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__REMOVE); if ( rc ) return rc; @@ -1576,18 +1554,17 @@ static int flask_deassign_device(struct domain *d, uint32_t machine_bdf) if ( rc ) return rc; - return rc = avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__REMOVE_DEVICE, NULL); + return avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__REMOVE_DEVICE, NULL); } static int flask_bind_pt_irq (struct domain *d, struct xen_domctl_bind_pt_irq *bind) { - u32 rsid; + u32 dsid, rsid; int rc = -EPERM; int irq; - struct domain_security_struct *ssec, *tsec; struct avc_audit_data ad; - rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE, RESOURCE__ADD); + rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__ADD); if ( rc ) return rc; @@ -1597,23 +1574,22 @@ static int flask_bind_pt_irq (struct domain *d, struct xen_domctl_bind_pt_irq *b if ( rc ) return rc; - ssec = current->domain->ssid; - rc = avc_has_perm(ssec->sid, rsid, SECCLASS_HVM, HVM__BIND_IRQ, &ad); + rc = avc_current_has_perm(rsid, SECCLASS_HVM, HVM__BIND_IRQ, &ad); if ( rc ) return rc; - tsec = d->ssid; - return avc_has_perm(tsec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__USE, &ad); + dsid = domain_sid(d); + return avc_has_perm(dsid, rsid, SECCLASS_RESOURCE, RESOURCE__USE, &ad); } static int flask_unbind_pt_irq (struct domain *d, struct xen_domctl_bind_pt_irq *bind) { - return domain_has_perm(current->domain, d, SECCLASS_RESOURCE, RESOURCE__REMOVE); + return current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__REMOVE); } static int flask_pin_mem_cacheattr (struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__CACHEATTR); + return current_has_perm(d, SECCLASS_HVM, HVM__CACHEATTR); } static int flask_ext_vcpucontext (struct domain *d, uint32_t cmd) @@ -1632,7 +1608,7 @@ static int flask_ext_vcpucontext (struct domain *d, uint32_t cmd) return -EPERM; } - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, perm); + return current_has_perm(d, SECCLASS_DOMAIN, perm); } static int flask_vcpuextstate (struct domain *d, uint32_t cmd) @@ -1651,7 +1627,7 @@ static int flask_vcpuextstate (struct domain *d, uint32_t cmd) return -EPERM; } - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, perm); + return current_has_perm(d, SECCLASS_DOMAIN, perm); } #endif diff --git a/xen/xsm/flask/include/objsec.h b/xen/xsm/flask/include/objsec.h index 4ff52be..6595dc3 100644 --- a/xen/xsm/flask/include/objsec.h +++ b/xen/xsm/flask/include/objsec.h @@ -19,6 +19,8 @@ struct domain_security_struct { u32 sid; /* current SID */ + u32 self_sid; /* SID for target when operating on DOMID_SELF */ + u32 target_sid; /* SID for device model target domain */ }; struct evtchn_security_struct { -- 1.7.11.7
Daniel De Graaf
2013-Jan-10 15:33 UTC
[PATCH 12/22] arch/x86: Add missing mem_sharing XSM hooks
This patch adds splits up the mem_sharing and mem_event XSM hooks to better cover what the code is doing. It also changes the utility function get_mem_event_op_target to rcu_lock_live_remote_domain_by_id because there is no mm-specific logic in there. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Acked-by: Tim Deegan <tim@xen.org> Acked-by: Jan Beulich <jbeulich@suse.com> Cc: Keir Fraser <keir@xen.org> --- xen/arch/x86/domctl.c | 8 +++----- xen/arch/x86/mm/mem_event.c | 41 +++++++++++-------------------------- xen/arch/x86/mm/mem_sharing.c | 25 ++++++++++++++++++---- xen/common/domain.c | 15 ++++++++++++++ xen/include/asm-x86/mem_event.h | 1 - xen/include/xen/sched.h | 6 ++++++ xen/include/xsm/dummy.h | 23 ++++++++++++++++++++- xen/include/xsm/xsm.h | 24 +++++++++++++++++++--- xen/xsm/dummy.c | 5 ++++- xen/xsm/flask/hooks.c | 25 ++++++++++++++++++++-- xen/xsm/flask/policy/access_vectors | 1 + 11 files changed, 128 insertions(+), 46 deletions(-) diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c index 0e81010..10558a0 100644 --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -1223,10 +1223,8 @@ long arch_do_domctl( case XEN_DOMCTL_mem_event_op: { - ret = xsm_mem_event(d); - if ( !ret ) - ret = mem_event_domctl(d, &domctl->u.mem_event_op, - guest_handle_cast(u_domctl, void)); + ret = mem_event_domctl(d, &domctl->u.mem_event_op, + guest_handle_cast(u_domctl, void)); copyback = 1; } break; @@ -1265,7 +1263,7 @@ long arch_do_domctl( if ( current->domain == d ) break; - ret = xsm_mem_event(d); + ret = xsm_mem_event_setup(d); if ( !ret ) { p2m = p2m_get_hostp2m(d); p2m->access_required = domctl->u.access_required.access_required; diff --git a/xen/arch/x86/mm/mem_event.c b/xen/arch/x86/mm/mem_event.c index 27d1cf4..c2b3670 100644 --- a/xen/arch/x86/mm/mem_event.c +++ b/xen/arch/x86/mm/mem_event.c @@ -29,6 +29,7 @@ #include <asm/mem_paging.h> #include <asm/mem_access.h> #include <asm/mem_sharing.h> +#include <xsm/xsm.h> /* for public/io/ring.h macros */ #define xen_mb() mb() @@ -439,35 +440,19 @@ static void mem_sharing_notification(struct vcpu *v, unsigned int port) mem_sharing_sharing_resume(v->domain); } -struct domain *get_mem_event_op_target(uint32_t domain, int *rc) -{ - struct domain *d; - - /* Get the target domain */ - *rc = rcu_lock_remote_target_domain_by_id(domain, &d); - if ( *rc != 0 ) - return NULL; - - /* Not dying? */ - if ( d->is_dying ) - { - rcu_unlock_domain(d); - *rc = -EINVAL; - return NULL; - } - - return d; -} - int do_mem_event_op(int op, uint32_t domain, void *arg) { int ret; struct domain *d; - d = get_mem_event_op_target(domain, &ret); - if ( !d ) + ret = rcu_lock_live_remote_domain_by_id(domain, &d); + if ( ret ) return ret; + ret = xsm_mem_event_op(d, op); + if ( ret ) + goto out; + switch (op) { case XENMEM_paging_op: @@ -483,6 +468,7 @@ int do_mem_event_op(int op, uint32_t domain, void *arg) ret = -ENOSYS; } + out: rcu_unlock_domain(d); return ret; } @@ -516,6 +502,10 @@ int mem_event_domctl(struct domain *d, xen_domctl_mem_event_op_t *mec, { int rc; + rc = xsm_mem_event_control(d, mec->mode, mec->op); + if ( rc ) + return rc; + if ( unlikely(d == current->domain) ) { gdprintk(XENLOG_INFO, "Tried to do a memory event op on itself.\n"); @@ -537,13 +527,6 @@ int mem_event_domctl(struct domain *d, xen_domctl_mem_event_op_t *mec, return -EINVAL; } - /* TODO: XSM hook */ -#if 0 - rc = xsm_mem_event_control(d, mec->op); - if ( rc ) - return rc; -#endif - rc = -ENOSYS; switch ( mec->mode ) diff --git a/xen/arch/x86/mm/mem_sharing.c b/xen/arch/x86/mm/mem_sharing.c index e91aac5..4624314 100644 --- a/xen/arch/x86/mm/mem_sharing.c +++ b/xen/arch/x86/mm/mem_sharing.c @@ -34,6 +34,7 @@ #include <asm/atomic.h> #include <xen/rcupdate.h> #include <asm/event.h> +#include <xsm/xsm.h> #include "mm-locks.h" @@ -1345,10 +1346,18 @@ int mem_sharing_memop(struct domain *d, xen_mem_sharing_op_t *mec) if ( !mem_sharing_enabled(d) ) return -EINVAL; - cd = get_mem_event_op_target(mec->u.share.client_domain, &rc); - if ( !cd ) + rc = rcu_lock_live_remote_domain_by_id(mec->u.share.client_domain, + &cd); + if ( rc ) return rc; + rc = xsm_mem_sharing_op(d, cd, mec->op); + if ( rc ) + { + rcu_unlock_domain(cd); + return rc; + } + if ( !mem_sharing_enabled(cd) ) { rcu_unlock_domain(cd); @@ -1401,10 +1410,18 @@ int mem_sharing_memop(struct domain *d, xen_mem_sharing_op_t *mec) if ( !mem_sharing_enabled(d) ) return -EINVAL; - cd = get_mem_event_op_target(mec->u.share.client_domain, &rc); - if ( !cd ) + rc = rcu_lock_live_remote_domain_by_id(mec->u.share.client_domain, + &cd); + if ( rc ) return rc; + rc = xsm_mem_sharing_op(d, cd, mec->op); + if ( rc ) + { + rcu_unlock_domain(cd); + return rc; + } + if ( !mem_sharing_enabled(cd) ) { rcu_unlock_domain(cd); diff --git a/xen/common/domain.c b/xen/common/domain.c index 2f8ef00..ec8efe8 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -475,6 +475,21 @@ int rcu_lock_remote_domain_by_id(domid_t dom, struct domain **d) return 0; } +int rcu_lock_live_remote_domain_by_id(domid_t dom, struct domain **d) +{ + int rv; + rv = rcu_lock_remote_domain_by_id(dom, d); + if ( rv ) + return rv; + if ( (*d)->is_dying ) + { + rcu_unlock_domain(*d); + return -EINVAL; + } + + return 0; +} + int domain_kill(struct domain *d) { int rc = 0; diff --git a/xen/include/asm-x86/mem_event.h b/xen/include/asm-x86/mem_event.h index e17f36b..5959621 100644 --- a/xen/include/asm-x86/mem_event.h +++ b/xen/include/asm-x86/mem_event.h @@ -62,7 +62,6 @@ void mem_event_put_request(struct domain *d, struct mem_event_domain *med, int mem_event_get_response(struct domain *d, struct mem_event_domain *med, mem_event_response_t *rsp); -struct domain *get_mem_event_op_target(uint32_t domain, int *rc); int do_mem_event_op(int op, uint32_t domain, void *arg); int mem_event_domctl(struct domain *d, xen_domctl_mem_event_op_t *mec, XEN_GUEST_HANDLE_PARAM(void) u_domctl); diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 6c55039..90a6537 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -484,6 +484,12 @@ int rcu_lock_remote_target_domain_by_id(domid_t dom, struct domain **d); */ int rcu_lock_remote_domain_by_id(domid_t dom, struct domain **d); +/* + * As rcu_lock_remote_domain_by_id() but will fail EINVAL if the domain is + * dying. + */ +int rcu_lock_live_remote_domain_by_id(domid_t dom, struct domain **d); + /* Finish a RCU critical region started by rcu_lock_domain_by_id(). */ static inline void rcu_unlock_domain(struct domain *d) { diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index e42965c..42b2285 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -551,16 +551,37 @@ static XSM_INLINE int xsm_hvm_inject_msi(struct domain *d) return 0; } -static XSM_INLINE int xsm_mem_event(struct domain *d) +static XSM_INLINE int xsm_mem_event_setup(struct domain *d) { return 0; } +static XSM_INLINE int xsm_mem_event_control(struct domain *d, int mode, int op) +{ + if ( !IS_PRIV(current->domain) ) + return -EPERM; + return 0; +} + +static XSM_INLINE int xsm_mem_event_op(struct domain *d, int op) +{ + if ( !IS_PRIV_FOR(current->domain, d) ) + return -EPERM; + return 0; +} + static XSM_INLINE int xsm_mem_sharing(struct domain *d) { return 0; } +static XSM_INLINE int xsm_mem_sharing_op(struct domain *d, struct domain *cd, int op) +{ + if ( !IS_PRIV_FOR(current->domain, cd) ) + return -EPERM; + return 0; +} + static XSM_INLINE int xsm_apic(struct domain *d, int cmd) { if ( !IS_PRIV(d) ) diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index 470e3c0..88aa95a 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -151,8 +151,11 @@ struct xsm_operations { int (*hvm_set_isa_irq_level) (struct domain *d); int (*hvm_set_pci_link_route) (struct domain *d); int (*hvm_inject_msi) (struct domain *d); - int (*mem_event) (struct domain *d); + int (*mem_event_setup) (struct domain *d); + int (*mem_event_control) (struct domain *d, int mode, int op); + int (*mem_event_op) (struct domain *d, int op); int (*mem_sharing) (struct domain *d); + int (*mem_sharing_op) (struct domain *d, struct domain *cd, int op); int (*apic) (struct domain *d, int cmd); int (*xen_settime) (void); int (*memtype) (uint32_t access); @@ -665,9 +668,19 @@ static inline int xsm_hvm_inject_msi (struct domain *d) return xsm_ops->hvm_inject_msi(d); } -static inline int xsm_mem_event (struct domain *d) +static inline int xsm_mem_event_setup (struct domain *d) { - return xsm_ops->mem_event(d); + return xsm_ops->mem_event_setup(d); +} + +static inline int xsm_mem_event_control (struct domain *d, int mode, int op) +{ + return xsm_ops->mem_event_control(d, mode, op); +} + +static inline int xsm_mem_event_op (struct domain *d, int op) +{ + return xsm_ops->mem_event_op(d, op); } static inline int xsm_mem_sharing (struct domain *d) @@ -675,6 +688,11 @@ static inline int xsm_mem_sharing (struct domain *d) return xsm_ops->mem_sharing(d); } +static inline int xsm_mem_sharing_op (struct domain *d, struct domain *cd, int op) +{ + return xsm_ops->mem_sharing_op(d, cd, op); +} + static inline int xsm_apic (struct domain *d, int cmd) { return xsm_ops->apic(d, cmd); diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c index 1e7f42c..bc9d30f 100644 --- a/xen/xsm/dummy.c +++ b/xen/xsm/dummy.c @@ -136,8 +136,11 @@ void xsm_fixup_ops (struct xsm_operations *ops) set_to_dummy_if_null(ops, hvm_set_isa_irq_level); set_to_dummy_if_null(ops, hvm_set_pci_link_route); set_to_dummy_if_null(ops, hvm_inject_msi); - set_to_dummy_if_null(ops, mem_event); + set_to_dummy_if_null(ops, mem_event_setup); + set_to_dummy_if_null(ops, mem_event_control); + set_to_dummy_if_null(ops, mem_event_op); set_to_dummy_if_null(ops, mem_sharing); + set_to_dummy_if_null(ops, mem_sharing_op); set_to_dummy_if_null(ops, apic); set_to_dummy_if_null(ops, xen_settime); set_to_dummy_if_null(ops, memtype); diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index eaf9650..f36fe2c 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -1278,7 +1278,17 @@ static int flask_hvm_inject_msi(struct domain *d) return current_has_perm(d, SECCLASS_HVM, HVM__SEND_IRQ); } -static int flask_mem_event(struct domain *d) +static int flask_mem_event_setup(struct domain *d) +{ + return current_has_perm(d, SECCLASS_HVM, HVM__MEM_EVENT); +} + +static int flask_mem_event_control(struct domain *d, int mode, int op) +{ + return current_has_perm(d, SECCLASS_HVM, HVM__MEM_EVENT); +} + +static int flask_mem_event_op(struct domain *d, int op) { return current_has_perm(d, SECCLASS_HVM, HVM__MEM_EVENT); } @@ -1288,6 +1298,14 @@ static int flask_mem_sharing(struct domain *d) return current_has_perm(d, SECCLASS_HVM, HVM__MEM_SHARING); } +static int flask_mem_sharing_op(struct domain *d, struct domain *cd, int op) +{ + int rc = current_has_perm(cd, SECCLASS_HVM, HVM__MEM_SHARING); + if ( rc ) + return rc; + return domain_has_perm(d, cd, SECCLASS_HVM, HVM__SHARE_MEM); +} + static int flask_apic(struct domain *d, int cmd) { u32 perm; @@ -1737,8 +1755,11 @@ static struct xsm_operations flask_ops = { .hvm_set_isa_irq_level = flask_hvm_set_isa_irq_level, .hvm_set_pci_link_route = flask_hvm_set_pci_link_route, .hvm_inject_msi = flask_hvm_inject_msi, - .mem_event = flask_mem_event, + .mem_event_setup = flask_mem_event_setup, + .mem_event_control = flask_mem_event_control, + .mem_event_op = flask_mem_event_op, .mem_sharing = flask_mem_sharing, + .mem_sharing_op = flask_mem_sharing_op, .apic = flask_apic, .xen_settime = flask_xen_settime, .memtype = flask_memtype, diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors index ea65e45..45ac437 100644 --- a/xen/xsm/flask/policy/access_vectors +++ b/xen/xsm/flask/policy/access_vectors @@ -102,6 +102,7 @@ class hvm mem_sharing audit_p2m send_irq + share_mem } class event -- 1.7.11.7
Daniel De Graaf
2013-Jan-10 15:33 UTC
[PATCH 13/22] arch/x86: use XSM hooks for get_pg_owner access checks
There are three callers of get_pg_owner: * do_mmuext_op, which does not have XSM hooks on all subfunctions * do_mmu_update, which has hooks that are inefficient * do_update_va_mapping_otherdomain, which has a simple XSM hook In order to preserve return values for the do_mmuext_op hypercall, an additional XSM hook is required to check the operation even for those subfunctions that do not use the pg_owner field. This also covers the MMUEXT_UNPIN_TABLE operation which did previously have an XSM hook. The XSM hooks in do_mmu_update were capable of replacing the checks in get_pg_owner; however, the hooks are buried in the inner loop of the function - not very good for performance when XSM is enabled and these turn in to indirect function calls. This patch removes the PTE from the hooks and replaces it with a bitfield describing what accesses are being requested. The XSM hook can then be called only when additional bits are set instead of once per iteration of the loop. This patch results in a change in the FLASK permissions used for mapping an MMIO page: the target for the permisison check on the memory mapping is no longer resolved to the device-specific type, and is instead either the domain''s own type or domio_t (depending on if the domain uses DOMID_SELF or DOMID_IO in the map command). Device-specific access is still controlled via the "resource use" permisison checked at domain creation (or device hotplug). Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Acked-by: Jan Beulich <jbeulich@suse.com> Acked-by: Tim Deegan <tim@xen.org> Cc: Keir Fraser <keir@xen.org> --- tools/flask/policy/policy/modules/xen/xen.if | 6 +-- tools/flask/policy/policy/modules/xen/xen.te | 5 +- xen/arch/x86/mm.c | 53 ++++++++++++--------- xen/include/xsm/dummy.h | 15 ++++-- xen/include/xsm/xsm.h | 25 +++++----- xen/xsm/dummy.c | 4 +- xen/xsm/flask/hooks.c | 71 ++++++++++------------------ xen/xsm/flask/policy/access_vectors | 1 + 8 files changed, 89 insertions(+), 91 deletions(-) diff --git a/tools/flask/policy/policy/modules/xen/xen.if b/tools/flask/policy/policy/modules/xen/xen.if index d630f47..fda5cb5 100644 --- a/tools/flask/policy/policy/modules/xen/xen.if +++ b/tools/flask/policy/policy/modules/xen/xen.if @@ -7,7 +7,7 @@ ################################################################################ define(`declare_domain_common'', ` allow $1 $2:grant { query setup }; - allow $1 $2:mmu { adjust physmap map_read map_write stat pinpage updatemp }; + allow $1 $2:mmu { adjust physmap map_read map_write stat pinpage updatemp mmuext_op }; allow $1 $2:hvm { getparam setparam }; '') @@ -51,7 +51,7 @@ define(`create_domain_common'', ` allow $1 $2:domain2 { set_cpuid settsc }; allow $1 $2:security check_context; allow $1 $2:shadow enable; - allow $1 $2:mmu {map_read map_write adjust memorymap physmap pinpage}; + allow $1 $2:mmu { map_read map_write adjust memorymap physmap pinpage mmuext_op }; allow $1 $2:grant setup; allow $1 $2:hvm { cacheattr getparam hvmctl irqlevel pciroute sethvmc setparam pcilevel trackdirtyvram }; '') @@ -162,7 +162,7 @@ define(`make_device_model'', ` # Allow a device to be used by a domain define(`use_device'', ` allow $1 $2:resource use; - allow $1 $2:mmu { map_read map_write }; + allow $1 domio_t:mmu { map_read map_write }; '') # admin_device(domain, device) diff --git a/tools/flask/policy/policy/modules/xen/xen.te b/tools/flask/policy/policy/modules/xen/xen.te index 8d33285..8c77e6b 100644 --- a/tools/flask/policy/policy/modules/xen/xen.te +++ b/tools/flask/policy/policy/modules/xen/xen.te @@ -29,10 +29,10 @@ type xen_t, xen_type, mls_priv; # Domain 0 declare_singleton_domain(dom0_t, mls_priv); -# Untracked I/O memory (pseudo-domain) +# I/O memory (DOMID_IO pseudo-domain) type domio_t, xen_type; -# Xen heap (pseudo-domain) +# Xen heap (DOMID_XEN pseudo-domain) type domxen_t, xen_type; # Unlabeled objects @@ -69,7 +69,6 @@ admin_device(dom0_t, device_t) admin_device(dom0_t, irq_t) admin_device(dom0_t, ioport_t) admin_device(dom0_t, iomem_t) -allow dom0_t domio_t:mmu { map_read map_write }; domain_comms(dom0_t, dom0_t) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 717fe68..c148a08 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -2605,11 +2605,6 @@ static struct domain *get_pg_owner(domid_t domid) pg_owner = rcu_lock_domain(dom_io); break; case DOMID_XEN: - if ( !IS_PRIV(curr) ) - { - MEM_LOG("Cannot set foreign dom"); - break; - } pg_owner = rcu_lock_domain(dom_xen); break; default: @@ -2618,12 +2613,6 @@ static struct domain *get_pg_owner(domid_t domid) MEM_LOG("Unknown domain ''%u''", domid); break; } - if ( !IS_PRIV_FOR(curr, pg_owner) ) - { - MEM_LOG("Cannot set foreign dom"); - rcu_unlock_domain(pg_owner); - pg_owner = NULL; - } break; } @@ -2711,6 +2700,13 @@ long do_mmuext_op( goto out; } + rc = xsm_mmuext_op(d, pg_owner); + if ( rc ) + { + rcu_unlock_domain(pg_owner); + goto out; + } + for ( i = 0; i < count; i++ ) { if ( hypercall_preempt_check() ) @@ -3153,6 +3149,8 @@ long do_mmu_update( struct vcpu *v = current; struct domain *d = v->domain, *pt_owner = d, *pg_owner; struct domain_mmap_cache mapcache; + uint32_t xsm_needed = 0; + uint32_t xsm_checked = 0; if ( unlikely(count & MMU_UPDATE_PREEMPTED) ) { @@ -3184,11 +3182,6 @@ long do_mmu_update( rc = -EINVAL; goto out; } - if ( !IS_PRIV_FOR(d, pt_owner) ) - { - rc = -ESRCH; - goto out; - } } if ( (pg_owner = get_pg_owner((uint16_t)foreigndom)) == NULL ) @@ -3228,9 +3221,20 @@ long do_mmu_update( { p2m_type_t p2mt; - rc = xsm_mmu_normal_update(d, pt_owner, pg_owner, req.val); - if ( rc ) - break; + xsm_needed |= XSM_MMU_NORMAL_UPDATE; + if ( get_pte_flags(req.val) & _PAGE_PRESENT ) + { + xsm_needed |= XSM_MMU_UPDATE_READ; + if ( get_pte_flags(req.val) & _PAGE_RW ) + xsm_needed |= XSM_MMU_UPDATE_WRITE; + } + if ( xsm_needed != xsm_checked ) + { + rc = xsm_mmu_update(d, pt_owner, pg_owner, xsm_needed); + if ( rc ) + break; + xsm_checked = xsm_needed; + } rc = -EINVAL; req.ptr -= cmd; @@ -3342,9 +3346,14 @@ long do_mmu_update( mfn = req.ptr >> PAGE_SHIFT; gpfn = req.val; - rc = xsm_mmu_machphys_update(d, pg_owner, mfn); - if ( rc ) - break; + xsm_needed |= XSM_MMU_MACHPHYS_UPDATE; + if ( xsm_needed != xsm_checked ) + { + rc = xsm_mmu_update(d, NULL, pg_owner, xsm_needed); + if ( rc ) + break; + xsm_checked = xsm_needed; + } if ( unlikely(!get_page_from_pagenr(mfn, pg_owner)) ) { diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index 42b2285..6648739 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -662,21 +662,28 @@ static XSM_INLINE int xsm_domain_memory_map(struct domain *d) return 0; } -static XSM_INLINE int xsm_mmu_normal_update(struct domain *d, struct domain *t, - struct domain *f, intpte_t fpte) +static XSM_INLINE int xsm_mmu_update(struct domain *d, struct domain *t, + struct domain *f, uint32_t flags) { + if ( t && d != t && !IS_PRIV_FOR(d, t) ) + return -EPERM; + if ( d != f && !IS_PRIV_FOR(d, f) ) + return -EPERM; return 0; } -static XSM_INLINE int xsm_mmu_machphys_update(struct domain *d, struct domain *f, - unsigned long mfn) +static XSM_INLINE int xsm_mmuext_op(struct domain *d, struct domain *f) { + if ( d != f && !IS_PRIV_FOR(d, f) ) + return -EPERM; return 0; } static XSM_INLINE int xsm_update_va_mapping(struct domain *d, struct domain *f, l1_pgentry_t pte) { + if ( d != f && !IS_PRIV_FOR(d, f) ) + return -EPERM; return 0; } diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index 88aa95a..d41eb54 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -27,8 +27,6 @@ typedef u32 xsm_magic_t; #define XSM_MAGIC 0x00000000 #endif -#ifdef XSM_ENABLE - extern char *policy_buffer; extern u32 policy_size; @@ -170,9 +168,13 @@ struct xsm_operations { int (*getidletime) (void); int (*machine_memory_map) (void); int (*domain_memory_map) (struct domain *d); - int (*mmu_normal_update) (struct domain *d, struct domain *t, - struct domain *f, intpte_t fpte); - int (*mmu_machphys_update) (struct domain *d1, struct domain *d2, unsigned long mfn); +#define XSM_MMU_UPDATE_READ 1 +#define XSM_MMU_UPDATE_WRITE 2 +#define XSM_MMU_NORMAL_UPDATE 4 +#define XSM_MMU_MACHPHYS_UPDATE 8 + int (*mmu_update) (struct domain *d, struct domain *t, + struct domain *f, uint32_t flags); + int (*mmuext_op) (struct domain *d, struct domain *f); int (*update_va_mapping) (struct domain *d, struct domain *f, l1_pgentry_t pte); int (*add_to_physmap) (struct domain *d1, struct domain *d2); int (*sendtrigger) (struct domain *d); @@ -186,6 +188,8 @@ struct xsm_operations { #endif }; +#ifdef XSM_ENABLE + extern struct xsm_operations *xsm_ops; #ifndef XSM_NO_WRAPPERS @@ -763,16 +767,15 @@ static inline int xsm_domain_memory_map(struct domain *d) return xsm_ops->domain_memory_map(d); } -static inline int xsm_mmu_normal_update (struct domain *d, struct domain *t, - struct domain *f, intpte_t fpte) +static inline int xsm_mmu_update (struct domain *d, struct domain *t, + struct domain *f, uint32_t flags) { - return xsm_ops->mmu_normal_update(d, t, f, fpte); + return xsm_ops->mmu_update(d, t, f, flags); } -static inline int xsm_mmu_machphys_update (struct domain *d1, struct domain *d2, - unsigned long mfn) +static inline int xsm_mmuext_op (struct domain *d, struct domain *f) { - return xsm_ops->mmu_machphys_update(d1, d2, mfn); + return xsm_ops->mmuext_op(d, f); } static inline int xsm_update_va_mapping(struct domain *d, struct domain *f, diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c index bc9d30f..200cbc8 100644 --- a/xen/xsm/dummy.c +++ b/xen/xsm/dummy.c @@ -155,8 +155,8 @@ void xsm_fixup_ops (struct xsm_operations *ops) set_to_dummy_if_null(ops, getidletime); set_to_dummy_if_null(ops, machine_memory_map); set_to_dummy_if_null(ops, domain_memory_map); - set_to_dummy_if_null(ops, mmu_normal_update); - set_to_dummy_if_null(ops, mmu_machphys_update); + set_to_dummy_if_null(ops, mmu_update); + set_to_dummy_if_null(ops, mmuext_op); set_to_dummy_if_null(ops, update_va_mapping); set_to_dummy_if_null(ops, add_to_physmap); set_to_dummy_if_null(ops, remove_from_physmap); diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index f36fe2c..ad60a88 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -1435,65 +1435,44 @@ static int flask_domain_memory_map(struct domain *d) return current_has_perm(d, SECCLASS_MMU, MMU__MEMORYMAP); } -static int domain_memory_perm(struct domain *d, struct domain *f, l1_pgentry_t pte) +static int flask_mmu_update(struct domain *d, struct domain *t, + struct domain *f, uint32_t flags) { int rc = 0; - u32 map_perms = MMU__MAP_READ; - unsigned long fgfn, fmfn; - p2m_type_t p2mt; - - if ( !(l1e_get_flags(pte) & _PAGE_PRESENT) ) - return 0; - - if ( l1e_get_flags(pte) & _PAGE_RW ) - map_perms |= MMU__MAP_WRITE; - - fgfn = l1e_get_pfn(pte); - fmfn = mfn_x(get_gfn_query(f, fgfn, &p2mt)); - put_gfn(f, fgfn); + u32 map_perms = 0; - if ( f->domain_id == DOMID_IO || !mfn_valid(fmfn) ) - { - struct avc_audit_data ad; - u32 dsid, fsid; - rc = security_iomem_sid(fmfn, &fsid); - if ( rc ) - return rc; - AVC_AUDIT_DATA_INIT(&ad, MEMORY); - ad.sdom = d; - ad.tdom = f; - ad.memory.pte = pte.l1; - ad.memory.mfn = fmfn; - dsid = domain_sid(d); - return avc_has_perm(dsid, fsid, SECCLASS_MMU, map_perms, &ad); - } - - return domain_has_perm(d, f, SECCLASS_MMU, map_perms); -} - -static int flask_mmu_normal_update(struct domain *d, struct domain *t, - struct domain *f, intpte_t fpte) -{ - int rc = 0; - - if (d != t) + if ( t && d != t ) rc = domain_has_perm(d, t, SECCLASS_MMU, MMU__REMOTE_REMAP); if ( rc ) return rc; - return domain_memory_perm(d, f, l1e_from_intpte(fpte)); + if ( flags & XSM_MMU_UPDATE_READ ) + map_perms |= MMU__MAP_READ; + if ( flags & XSM_MMU_UPDATE_WRITE ) + map_perms |= MMU__MAP_WRITE; + if ( flags & XSM_MMU_MACHPHYS_UPDATE ) + map_perms |= MMU__UPDATEMP; + + if ( map_perms ) + rc = domain_has_perm(d, f, SECCLASS_MMU, map_perms); + return rc; } -static int flask_mmu_machphys_update(struct domain *d1, struct domain *d2, - unsigned long mfn) +static int flask_mmuext_op(struct domain *d, struct domain *f) { - return domain_has_perm(d1, d2, SECCLASS_MMU, MMU__UPDATEMP); + return domain_has_perm(d, f, SECCLASS_MMU, MMU__MMUEXT_OP); } static int flask_update_va_mapping(struct domain *d, struct domain *f, l1_pgentry_t pte) { - return domain_memory_perm(d, f, pte); + u32 map_perms = MMU__MAP_READ; + if ( !(l1e_get_flags(pte) & _PAGE_PRESENT) ) + return 0; + if ( l1e_get_flags(pte) & _PAGE_RW ) + map_perms |= MMU__MAP_WRITE; + + return domain_has_perm(d, f, SECCLASS_MMU, map_perms); } static int flask_add_to_physmap(struct domain *d1, struct domain *d2) @@ -1774,8 +1753,8 @@ static struct xsm_operations flask_ops = { .getidletime = flask_getidletime, .machine_memory_map = flask_machine_memory_map, .domain_memory_map = flask_domain_memory_map, - .mmu_normal_update = flask_mmu_normal_update, - .mmu_machphys_update = flask_mmu_machphys_update, + .mmu_update = flask_mmu_update, + .mmuext_op = flask_mmuext_op, .update_va_mapping = flask_update_va_mapping, .add_to_physmap = flask_add_to_physmap, .remove_from_physmap = flask_remove_from_physmap, diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors index 45ac437..8324725 100644 --- a/xen/xsm/flask/policy/access_vectors +++ b/xen/xsm/flask/policy/access_vectors @@ -141,6 +141,7 @@ class mmu mfnlist memorymap remote_remap + mmuext_op } class shadow -- 1.7.11.7
Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Cc: Keir Fraser <keir@xen.org> --- tools/flask/policy/policy/modules/xen/xen.if | 2 ++ xen/common/memory.c | 12 +++++++++++- xen/include/xsm/dummy.h | 7 +++++++ xen/include/xsm/xsm.h | 6 ++++++ xen/xsm/dummy.c | 1 + xen/xsm/flask/hooks.c | 6 ++++++ xen/xsm/flask/policy/access_vectors | 1 + 7 files changed, 34 insertions(+), 1 deletion(-) diff --git a/tools/flask/policy/policy/modules/xen/xen.if b/tools/flask/policy/policy/modules/xen/xen.if index fda5cb5..d9d5344 100644 --- a/tools/flask/policy/policy/modules/xen/xen.if +++ b/tools/flask/policy/policy/modules/xen/xen.if @@ -30,6 +30,7 @@ define(`declare_domain'', ` # containing at most one domain. This is not enforced by policy. define(`declare_singleton_domain'', ` type $1, domain_type`''ifelse(`$#'', `1'', `'', `,shift($@)''); + define(`$1_self'', `$1'') type $1_channel, event_type; type_transition $1 domain_type:event $1_channel; declare_domain_common($1, $1) @@ -161,6 +162,7 @@ define(`make_device_model'', ` # use_device(domain, device) # Allow a device to be used by a domain define(`use_device'', ` + allow $1 $1_self:mmu exchange; allow $1 $2:resource use; allow $1 domio_t:mmu { map_read map_write }; '') diff --git a/xen/common/memory.c b/xen/common/memory.c index 35acf1c..e18e224 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -341,9 +341,19 @@ static long memory_exchange(XEN_GUEST_HANDLE_PARAM(xen_memory_exchange_t) arg) out_chunk_order = exch.in.extent_order - exch.out.extent_order; } - rc = rcu_lock_target_domain_by_id(exch.in.domid, &d); + d = rcu_lock_domain_by_any_id(exch.in.domid); + if ( d == NULL ) + { + rc = -ESRCH; + goto fail_early; + } + + rc = xsm_memory_exchange(d); if ( rc ) + { + rcu_unlock_domain(d); goto fail_early; + } memflags |= MEMF_bits(domain_clamp_alloc_bitsize( d, diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index 6648739..9894d8d 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -235,6 +235,13 @@ static XSM_INLINE int xsm_grant_query_size(struct domain *d1, struct domain *d2) return 0; } +static XSM_INLINE int xsm_memory_exchange(struct domain *d) +{ + if ( d != current->domain && !IS_PRIV_FOR(current->domain, d) ) + return -EPERM; + return 0; +} + static XSM_INLINE int xsm_memory_adjust_reservation(struct domain *d1, struct domain *d2) { diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index d41eb54..a8c1d87 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -96,6 +96,7 @@ struct xsm_operations { int (*get_pod_target) (struct domain *d); int (*set_pod_target) (struct domain *d); + int (*memory_exchange) (struct domain *d); int (*memory_adjust_reservation) (struct domain *d1, struct domain *d2); int (*memory_stat_reservation) (struct domain *d1, struct domain *d2); int (*memory_pin_page) (struct domain *d1, struct domain *d2, struct page_info *page); @@ -453,6 +454,11 @@ static inline int xsm_set_pod_target (struct domain *d) return xsm_ops->set_pod_target(d); } +static inline int xsm_memory_exchange (struct domain *d) +{ + return xsm_ops->memory_exchange(d); +} + static inline int xsm_memory_adjust_reservation (struct domain *d1, struct domain *d2) { diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c index 200cbc8..71299d5 100644 --- a/xen/xsm/dummy.c +++ b/xen/xsm/dummy.c @@ -84,6 +84,7 @@ void xsm_fixup_ops (struct xsm_operations *ops) set_to_dummy_if_null(ops, get_pod_target); set_to_dummy_if_null(ops, set_pod_target); + set_to_dummy_if_null(ops, memory_exchange); set_to_dummy_if_null(ops, memory_adjust_reservation); set_to_dummy_if_null(ops, memory_stat_reservation); set_to_dummy_if_null(ops, memory_pin_page); diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index ad60a88..7707ac2 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -396,6 +396,11 @@ static int flask_set_pod_target(struct domain *d) return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETPODTARGET); } +static int flask_memory_exchange(struct domain *d) +{ + return current_has_perm(d, SECCLASS_MMU, MMU__EXCHANGE); +} + static int flask_memory_adjust_reservation(struct domain *d1, struct domain *d2) { return domain_has_perm(d1, d2, SECCLASS_MMU, MMU__ADJUST); @@ -1686,6 +1691,7 @@ static struct xsm_operations flask_ops = { .get_pod_target = flask_get_pod_target, .set_pod_target = flask_set_pod_target, + .memory_exchange = flask_memory_exchange, .memory_adjust_reservation = flask_memory_adjust_reservation, .memory_stat_reservation = flask_memory_stat_reservation, .memory_pin_page = flask_memory_pin_page, diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors index 8324725..caf65d2 100644 --- a/xen/xsm/flask/policy/access_vectors +++ b/xen/xsm/flask/policy/access_vectors @@ -142,6 +142,7 @@ class mmu memorymap remote_remap mmuext_op + exchange } class shadow -- 1.7.11.7
A number of the domctl XSM hooks do nothing except pass the domain and operation ID, making them redundant with the xsm_domctl hook. Remove these redundant hooks. The remaining domctls all use individual hooks because they pass extra details of the call to the XSM module in order to allow a more fine-grained access decision to be made - for example, considering the exact device or memory range being set up for guest access. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Cc: Keir Fraser <keir@xen.org> Cc: Jan Beulich <jbeulich@suse.com> --- xen/arch/x86/domctl.c | 76 +--------- xen/common/domctl.c | 59 +------- xen/include/xsm/dummy.h | 135 ----------------- xen/include/xsm/xsm.h | 161 --------------------- xen/xsm/dummy.c | 27 ---- xen/xsm/flask/hooks.c | 378 ++++++++++++------------------------------------ 6 files changed, 98 insertions(+), 738 deletions(-) diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c index 10558a0..6ab2006 100644 --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -97,10 +97,6 @@ long arch_do_domctl( page = mfn_to_page(mfn); - ret = xsm_getpageframeinfo(d); - if ( ret ) - break; - if ( likely(get_page(page, d)) ) { ret = 0; @@ -141,10 +137,6 @@ long arch_do_domctl( struct page_info *page; xen_pfn_t *arr; - ret = xsm_getpageframeinfo(d); - if ( ret ) - break; - if ( unlikely(num > 1024) || unlikely(num != domctl->u.getpageframeinfo3.num) ) { @@ -239,10 +231,6 @@ long arch_do_domctl( int num = domctl->u.getpageframeinfo2.num; uint32_t *arr32; - ret = xsm_getpageframeinfo(d); - if ( ret ) - break; - if ( unlikely(num > 1024) ) { ret = -E2BIG; @@ -334,10 +322,6 @@ long arch_do_domctl( uint64_t mfn; struct page_info *page; - ret = xsm_getmemlist(d); - if ( ret ) - break; - if ( unlikely(d->is_dying) ) { ret = -EINVAL; break; @@ -373,10 +357,6 @@ long arch_do_domctl( struct page_info *page; void *hypercall_page; - ret = xsm_hypercall_init(d); - if ( ret ) - break; - page = get_page_from_gfn(d, gmfn, NULL, P2M_ALLOC); ret = -EACCES; @@ -401,10 +381,6 @@ long arch_do_domctl( { struct hvm_domain_context c = { .size = domctl->u.hvmcontext.size }; - ret = xsm_hvmcontext(d, domctl->cmd); - if ( ret ) - goto sethvmcontext_out; - ret = -EINVAL; if ( !is_hvm_domain(d) ) goto sethvmcontext_out; @@ -431,10 +407,6 @@ long arch_do_domctl( { struct hvm_domain_context c = { 0 }; - ret = xsm_hvmcontext(d, domctl->cmd); - if ( ret ) - goto gethvmcontext_out; - ret = -EINVAL; if ( !is_hvm_domain(d) ) goto gethvmcontext_out; @@ -477,10 +449,6 @@ long arch_do_domctl( case XEN_DOMCTL_gethvmcontext_partial: { - ret = xsm_hvmcontext(d, domctl->cmd); - if ( ret ) - break; - ret = -EINVAL; if ( !is_hvm_domain(d) ) break; @@ -496,10 +464,6 @@ long arch_do_domctl( case XEN_DOMCTL_set_address_size: { - ret = xsm_address_size(d, domctl->cmd); - if ( ret ) - break; - switch ( domctl->u.address_size.size ) { case 32: @@ -517,10 +481,6 @@ long arch_do_domctl( case XEN_DOMCTL_get_address_size: { - ret = xsm_address_size(d, domctl->cmd); - if ( ret ) - break; - domctl->u.address_size.size is_pv_32on64_domain(d) ? 32 : BITS_PER_LONG; @@ -531,10 +491,6 @@ long arch_do_domctl( case XEN_DOMCTL_set_machine_address_size: { - ret = xsm_machine_address_size(d, domctl->cmd); - if ( ret ) - break; - ret = -EBUSY; if ( d->tot_pages > 0 ) break; @@ -547,10 +503,6 @@ long arch_do_domctl( case XEN_DOMCTL_get_machine_address_size: { - ret = xsm_machine_address_size(d, domctl->cmd); - if ( ret ) - break; - domctl->u.address_size.size = d->arch.physaddr_bitsize; ret = 0; @@ -562,10 +514,6 @@ long arch_do_domctl( { struct vcpu *v; - ret = xsm_sendtrigger(d); - if ( ret ) - break; - ret = -EINVAL; if ( domctl->u.sendtrigger.vcpu >= MAX_VIRT_CPUS ) break; @@ -832,10 +780,6 @@ long arch_do_domctl( case XEN_DOMCTL_pin_mem_cacheattr: { - ret = xsm_pin_mem_cacheattr(d); - if ( ret ) - break; - ret = hvm_set_mem_pinned_cacheattr( d, domctl->u.pin_mem_cacheattr.start, domctl->u.pin_mem_cacheattr.end, @@ -851,10 +795,6 @@ long arch_do_domctl( evc = &domctl->u.ext_vcpucontext; - ret = xsm_ext_vcpucontext(d, domctl->cmd); - if ( ret ) - break; - ret = -ESRCH; if ( (evc->vcpu >= d->max_vcpus) || ((v = d->vcpu[evc->vcpu]) == NULL) ) @@ -1118,10 +1058,6 @@ long arch_do_domctl( evc = &domctl->u.vcpuextstate; - ret = xsm_vcpuextstate(d, domctl->cmd); - if ( ret ) - goto vcpuextstate_out; - ret = -ESRCH; if ( (evc->vcpu >= d->max_vcpus) || ((v = d->vcpu[evc->vcpu]) == NULL) ) @@ -1231,9 +1167,7 @@ long arch_do_domctl( case XEN_DOMCTL_mem_sharing_op: { - ret = xsm_mem_sharing(d); - if ( !ret ) - ret = mem_sharing_domctl(d, &domctl->u.mem_sharing_op); + ret = mem_sharing_domctl(d, &domctl->u.mem_sharing_op); } break; @@ -1263,11 +1197,9 @@ long arch_do_domctl( if ( current->domain == d ) break; - ret = xsm_mem_event_setup(d); - if ( !ret ) { - p2m = p2m_get_hostp2m(d); - p2m->access_required = domctl->u.access_required.access_required; - } + ret = 0; + p2m = p2m_get_hostp2m(d); + p2m->access_required = domctl->u.access_required.access_required; } break; diff --git a/xen/common/domctl.c b/xen/common/domctl.c index b32e614..e1fb75d 100644 --- a/xen/common/domctl.c +++ b/xen/common/domctl.c @@ -290,10 +290,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) if ( d == NULL ) break; - ret = xsm_setvcpucontext(d); - if ( ret ) - goto svc_out; - ret = -EINVAL; if ( (d == current->domain) || /* no domain_pause() */ (vcpu >= d->max_vcpus) || ((v = d->vcpu[vcpu]) == NULL) ) @@ -340,10 +336,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) case XEN_DOMCTL_pausedomain: { - ret = xsm_pausedomain(d); - if ( ret ) - break; - ret = -EINVAL; if ( d != current->domain ) { @@ -355,10 +347,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) case XEN_DOMCTL_unpausedomain: { - ret = xsm_unpausedomain(d); - if ( ret ) - break; - domain_unpause_by_systemcontroller(d); ret = 0; } @@ -366,10 +354,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) case XEN_DOMCTL_resumedomain: { - ret = xsm_resumedomain(d); - if ( ret ) - break; - domain_resume(d); ret = 0; } @@ -452,10 +436,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) (is_hvm_domain(d) && (max > MAX_HVM_VCPUS)) ) break; - ret = xsm_max_vcpus(d); - if ( ret ) - break; - /* Until Xenoprof can dynamically grow its vcpu-s array... */ if ( d->xenoprof ) { @@ -538,7 +518,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) case XEN_DOMCTL_destroydomain: { - ret = xsm_destroydomain(d) ? : domain_kill(d); + ret = domain_kill(d); } break; @@ -547,10 +527,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) { struct vcpu *v; - ret = xsm_vcpuaffinity(op->cmd, d); - if ( ret ) - break; - ret = -EINVAL; if ( op->u.vcpuaffinity.vcpu >= d->max_vcpus ) break; @@ -581,10 +557,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) case XEN_DOMCTL_scheduler_op: { - ret = xsm_scheduler(d); - if ( ret ) - break; - ret = sched_adjust(d, &op->u.scheduler_op); copyback = 1; } @@ -627,10 +599,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) vcpu_guest_context_u c = { .nat = NULL }; struct vcpu *v; - ret = xsm_getvcpucontext(d); - if ( ret ) - goto getvcpucontext_out; - ret = -EINVAL; if ( op->u.vcpucontext.vcpu >= d->max_vcpus ) goto getvcpucontext_out; @@ -684,10 +652,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) struct vcpu *v; struct vcpu_runstate_info runstate; - ret = xsm_getvcpuinfo(d); - if ( ret ) - break; - ret = -EINVAL; if ( op->u.getvcpuinfo.vcpu >= d->max_vcpus ) break; @@ -712,10 +676,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) { unsigned long new_max; - ret = xsm_setdomainmaxmem(d); - if ( ret ) - break; - ret = -EINVAL; new_max = op->u.max_mem.max_memkb >> (PAGE_SHIFT-10); @@ -733,10 +693,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) case XEN_DOMCTL_setdomainhandle: { - ret = xsm_setdomainhandle(d); - if ( ret ) - break; - memcpy(d->handle, op->u.setdomainhandle.handle, sizeof(xen_domain_handle_t)); ret = 0; @@ -749,10 +705,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) if ( d == current->domain ) /* no domain_pause() */ break; - ret = xsm_setdebugging(d); - if ( ret ) - break; - domain_pause(d); d->debugger_attached = !!op->u.setdebugging.enable; domain_unpause(d); /* causes guest to latch new status */ @@ -797,10 +749,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) case XEN_DOMCTL_settimeoffset: { - ret = xsm_domain_settime(d); - if ( ret ) - break; - domain_set_time_offset(d, op->u.settimeoffset.time_offset_seconds); ret = 0; } @@ -850,10 +798,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) case XEN_DOMCTL_set_virq_handler: { uint32_t virq = op->u.set_virq_handler.virq; - - ret = xsm_set_virq_handler(d, virq); - if ( !ret ) - ret = set_global_virq_handler(d, virq); + ret = set_global_virq_handler(d, virq); } break; diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index 9894d8d..2b18f51 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -17,71 +17,16 @@ static XSM_INLINE void xsm_security_domaininfo(struct domain *d, return; } -static XSM_INLINE int xsm_setvcpucontext(struct domain *d) -{ - return 0; -} - -static XSM_INLINE int xsm_pausedomain(struct domain *d) -{ - return 0; -} - -static XSM_INLINE int xsm_unpausedomain(struct domain *d) -{ - return 0; -} - -static XSM_INLINE int xsm_resumedomain(struct domain *d) -{ - return 0; -} - static XSM_INLINE int xsm_domain_create(struct domain *d, u32 ssidref) { return 0; } -static XSM_INLINE int xsm_max_vcpus(struct domain *d) -{ - return 0; -} - -static XSM_INLINE int xsm_destroydomain(struct domain *d) -{ - return 0; -} - -static XSM_INLINE int xsm_vcpuaffinity(int cmd, struct domain *d) -{ - return 0; -} - -static XSM_INLINE int xsm_scheduler(struct domain *d) -{ - return 0; -} - static XSM_INLINE int xsm_getdomaininfo(struct domain *d) { return 0; } -static XSM_INLINE int xsm_getvcpucontext(struct domain *d) -{ - return 0; -} - -static XSM_INLINE int xsm_getvcpuinfo(struct domain *d) -{ - return 0; -} - -static XSM_INLINE int xsm_domain_settime(struct domain *d) -{ - return 0; -} - static XSM_INLINE int xsm_set_target(struct domain *d, struct domain *e) { return 0; @@ -113,11 +58,6 @@ static XSM_INLINE int xsm_sysctl(int cmd) return 0; } -static XSM_INLINE int xsm_set_virq_handler(struct domain *d, uint32_t virq) -{ - return 0; -} - static XSM_INLINE int xsm_tbufcontrol(void) { return 0; @@ -133,21 +73,6 @@ static XSM_INLINE int xsm_sched_id(void) return 0; } -static XSM_INLINE int xsm_setdomainmaxmem(struct domain *d) -{ - return 0; -} - -static XSM_INLINE int xsm_setdomainhandle(struct domain *d) -{ - return 0; -} - -static XSM_INLINE int xsm_setdebugging(struct domain *d) -{ - return 0; -} - static XSM_INLINE int xsm_perfcontrol(void) { return 0; @@ -493,36 +418,6 @@ static XSM_INLINE int xsm_shadow_control(struct domain *d, uint32_t op) return 0; } -static XSM_INLINE int xsm_getpageframeinfo(struct domain *d) -{ - return 0; -} - -static XSM_INLINE int xsm_getmemlist(struct domain *d) -{ - return 0; -} - -static XSM_INLINE int xsm_hypercall_init(struct domain *d) -{ - return 0; -} - -static XSM_INLINE int xsm_hvmcontext(struct domain *d, uint32_t cmd) -{ - return 0; -} - -static XSM_INLINE int xsm_address_size(struct domain *d, uint32_t cmd) -{ - return 0; -} - -static XSM_INLINE int xsm_machine_address_size(struct domain *d, uint32_t cmd) -{ - return 0; -} - static XSM_INLINE int xsm_hvm_param(struct domain *d, unsigned long op) { if ( current->domain != d && !IS_PRIV_FOR(current->domain, d) ) @@ -558,11 +453,6 @@ static XSM_INLINE int xsm_hvm_inject_msi(struct domain *d) return 0; } -static XSM_INLINE int xsm_mem_event_setup(struct domain *d) -{ - return 0; -} - static XSM_INLINE int xsm_mem_event_control(struct domain *d, int mode, int op) { if ( !IS_PRIV(current->domain) ) @@ -577,11 +467,6 @@ static XSM_INLINE int xsm_mem_event_op(struct domain *d, int op) return 0; } -static XSM_INLINE int xsm_mem_sharing(struct domain *d) -{ - return 0; -} - static XSM_INLINE int xsm_mem_sharing_op(struct domain *d, struct domain *cd, int op) { if ( !IS_PRIV_FOR(current->domain, cd) ) @@ -708,11 +593,6 @@ static XSM_INLINE int xsm_remove_from_physmap(struct domain *d1, struct domain * return 0; } -static XSM_INLINE int xsm_sendtrigger(struct domain *d) -{ - return 0; -} - static XSM_INLINE int xsm_bind_pt_irq(struct domain *d, struct xen_domctl_bind_pt_irq *bind) { return 0; @@ -723,21 +603,6 @@ static XSM_INLINE int xsm_unbind_pt_irq(struct domain *d, struct xen_domctl_bind return 0; } -static XSM_INLINE int xsm_pin_mem_cacheattr(struct domain *d) -{ - return 0; -} - -static XSM_INLINE int xsm_ext_vcpucontext(struct domain *d, uint32_t cmd) -{ - return 0; -} - -static XSM_INLINE int xsm_vcpuextstate(struct domain *d, uint32_t cmd) -{ - return 0; -} - static XSM_INLINE int xsm_ioport_permission(struct domain *d, uint32_t s, uint32_t e, uint8_t allow) { return 0; diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index a8c1d87..4676c75 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -41,29 +41,14 @@ extern xsm_initcall_t __xsm_initcall_start[], __xsm_initcall_end[]; struct xsm_operations { void (*security_domaininfo) (struct domain *d, struct xen_domctl_getdomaininfo *info); - int (*setvcpucontext) (struct domain *d); - int (*pausedomain) (struct domain *d); - int (*unpausedomain) (struct domain *d); - int (*resumedomain) (struct domain *d); int (*domain_create) (struct domain *d, u32 ssidref); - int (*max_vcpus) (struct domain *d); - int (*destroydomain) (struct domain *d); - int (*vcpuaffinity) (int cmd, struct domain *d); - int (*scheduler) (struct domain *d); int (*getdomaininfo) (struct domain *d); - int (*getvcpucontext) (struct domain *d); - int (*getvcpuinfo) (struct domain *d); - int (*domain_settime) (struct domain *d); int (*set_target) (struct domain *d, struct domain *e); int (*domctl) (struct domain *d, int cmd); int (*sysctl) (int cmd); - int (*set_virq_handler) (struct domain *d, uint32_t virq); int (*tbufcontrol) (void); int (*readconsole) (uint32_t clear); int (*sched_id) (void); - int (*setdomainmaxmem) (struct domain *d); - int (*setdomainhandle) (struct domain *d); - int (*setdebugging) (struct domain *d); int (*perfcontrol) (void); int (*debug_keys) (void); int (*getcpuinfo) (void); @@ -139,21 +124,13 @@ struct xsm_operations { #ifdef CONFIG_X86 int (*shadow_control) (struct domain *d, uint32_t op); - int (*getpageframeinfo) (struct domain *d); - int (*getmemlist) (struct domain *d); - int (*hypercall_init) (struct domain *d); - int (*hvmcontext) (struct domain *d, uint32_t op); - int (*address_size) (struct domain *d, uint32_t op); - int (*machine_address_size) (struct domain *d, uint32_t op); int (*hvm_param) (struct domain *d, unsigned long op); int (*hvm_set_pci_intx_level) (struct domain *d); int (*hvm_set_isa_irq_level) (struct domain *d); int (*hvm_set_pci_link_route) (struct domain *d); int (*hvm_inject_msi) (struct domain *d); - int (*mem_event_setup) (struct domain *d); int (*mem_event_control) (struct domain *d, int mode, int op); int (*mem_event_op) (struct domain *d, int op); - int (*mem_sharing) (struct domain *d); int (*mem_sharing_op) (struct domain *d, struct domain *cd, int op); int (*apic) (struct domain *d, int cmd); int (*xen_settime) (void); @@ -178,12 +155,8 @@ struct xsm_operations { int (*mmuext_op) (struct domain *d, struct domain *f); int (*update_va_mapping) (struct domain *d, struct domain *f, l1_pgentry_t pte); int (*add_to_physmap) (struct domain *d1, struct domain *d2); - int (*sendtrigger) (struct domain *d); int (*bind_pt_irq) (struct domain *d, struct xen_domctl_bind_pt_irq *bind); int (*unbind_pt_irq) (struct domain *d, struct xen_domctl_bind_pt_irq *bind); - int (*pin_mem_cacheattr) (struct domain *d); - int (*ext_vcpucontext) (struct domain *d, uint32_t cmd); - int (*vcpuextstate) (struct domain *d, uint32_t cmd); int (*ioport_permission) (struct domain *d, uint32_t s, uint32_t e, uint8_t allow); int (*ioport_mapping) (struct domain *d, uint32_t s, uint32_t e, uint8_t allow); #endif @@ -201,71 +174,16 @@ static inline void xsm_security_domaininfo (struct domain *d, xsm_ops->security_domaininfo(d, info); } -static inline int xsm_setvcpucontext(struct domain *d) -{ - return xsm_ops->setvcpucontext(d); -} - -static inline int xsm_pausedomain (struct domain *d) -{ - return xsm_ops->pausedomain(d); -} - -static inline int xsm_unpausedomain (struct domain *d) -{ - return xsm_ops->unpausedomain(d); -} - -static inline int xsm_resumedomain (struct domain *d) -{ - return xsm_ops->resumedomain(d); -} - static inline int xsm_domain_create (struct domain *d, u32 ssidref) { return xsm_ops->domain_create(d, ssidref); } -static inline int xsm_max_vcpus(struct domain *d) -{ - return xsm_ops->max_vcpus(d); -} - -static inline int xsm_destroydomain (struct domain *d) -{ - return xsm_ops->destroydomain(d); -} - -static inline int xsm_vcpuaffinity (int cmd, struct domain *d) -{ - return xsm_ops->vcpuaffinity(cmd, d); -} - -static inline int xsm_scheduler (struct domain *d) -{ - return xsm_ops->scheduler(d); -} - static inline int xsm_getdomaininfo (struct domain *d) { return xsm_ops->getdomaininfo(d); } -static inline int xsm_getvcpucontext (struct domain *d) -{ - return xsm_ops->getvcpucontext(d); -} - -static inline int xsm_getvcpuinfo (struct domain *d) -{ - return xsm_ops->getvcpuinfo(d); -} - -static inline int xsm_domain_settime (struct domain *d) -{ - return xsm_ops->domain_settime(d); -} - static inline int xsm_set_target (struct domain *d, struct domain *e) { return xsm_ops->set_target(d, e); @@ -281,11 +199,6 @@ static inline int xsm_sysctl (int cmd) return xsm_ops->sysctl(cmd); } -static inline int xsm_set_virq_handler (struct domain *d, uint32_t virq) -{ - return xsm_ops->set_virq_handler(d, virq); -} - static inline int xsm_tbufcontrol (void) { return xsm_ops->tbufcontrol(); @@ -301,21 +214,6 @@ static inline int xsm_sched_id (void) return xsm_ops->sched_id(); } -static inline int xsm_setdomainmaxmem (struct domain *d) -{ - return xsm_ops->setdomainmaxmem(d); -} - -static inline int xsm_setdomainhandle (struct domain *d) -{ - return xsm_ops->setdomainhandle(d); -} - -static inline int xsm_setdebugging (struct domain *d) -{ - return xsm_ops->setdebugging(d); -} - static inline int xsm_perfcontrol (void) { return xsm_ops->perfcontrol(); @@ -623,36 +521,6 @@ static inline int xsm_shadow_control (struct domain *d, uint32_t op) return xsm_ops->shadow_control(d, op); } -static inline int xsm_getpageframeinfo (struct domain *d) -{ - return xsm_ops->getpageframeinfo(d); -} - -static inline int xsm_getmemlist (struct domain *d) -{ - return xsm_ops->getmemlist(d); -} - -static inline int xsm_hypercall_init (struct domain *d) -{ - return xsm_ops->hypercall_init(d); -} - -static inline int xsm_hvmcontext (struct domain *d, uint32_t cmd) -{ - return xsm_ops->hvmcontext(d, cmd); -} - -static inline int xsm_address_size (struct domain *d, uint32_t cmd) -{ - return xsm_ops->address_size(d, cmd); -} - -static inline int xsm_machine_address_size (struct domain *d, uint32_t cmd) -{ - return xsm_ops->machine_address_size(d, cmd); -} - static inline int xsm_hvm_param (struct domain *d, unsigned long op) { return xsm_ops->hvm_param(d, op); @@ -678,11 +546,6 @@ static inline int xsm_hvm_inject_msi (struct domain *d) return xsm_ops->hvm_inject_msi(d); } -static inline int xsm_mem_event_setup (struct domain *d) -{ - return xsm_ops->mem_event_setup(d); -} - static inline int xsm_mem_event_control (struct domain *d, int mode, int op) { return xsm_ops->mem_event_control(d, mode, op); @@ -693,11 +556,6 @@ static inline int xsm_mem_event_op (struct domain *d, int op) return xsm_ops->mem_event_op(d, op); } -static inline int xsm_mem_sharing (struct domain *d) -{ - return xsm_ops->mem_sharing(d); -} - static inline int xsm_mem_sharing_op (struct domain *d, struct domain *cd, int op) { return xsm_ops->mem_sharing_op(d, cd, op); @@ -795,11 +653,6 @@ static inline int xsm_add_to_physmap(struct domain *d1, struct domain *d2) return xsm_ops->add_to_physmap(d1, d2); } -static inline int xsm_sendtrigger(struct domain *d) -{ - return xsm_ops->sendtrigger(d); -} - static inline int xsm_bind_pt_irq(struct domain *d, struct xen_domctl_bind_pt_irq *bind) { @@ -812,20 +665,6 @@ static inline int xsm_unbind_pt_irq(struct domain *d, return xsm_ops->unbind_pt_irq(d, bind); } -static inline int xsm_pin_mem_cacheattr(struct domain *d) -{ - return xsm_ops->pin_mem_cacheattr(d); -} - -static inline int xsm_ext_vcpucontext(struct domain *d, uint32_t cmd) -{ - return xsm_ops->ext_vcpucontext(d, cmd); -} -static inline int xsm_vcpuextstate(struct domain *d, uint32_t cmd) -{ - return xsm_ops->vcpuextstate(d, cmd); -} - static inline int xsm_ioport_permission (struct domain *d, uint32_t s, uint32_t e, uint8_t allow) { return xsm_ops->ioport_permission(d, s, e, allow); diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c index 71299d5..a14a755 100644 --- a/xen/xsm/dummy.c +++ b/xen/xsm/dummy.c @@ -30,29 +30,14 @@ struct xsm_operations dummy_xsm_ops; void xsm_fixup_ops (struct xsm_operations *ops) { set_to_dummy_if_null(ops, security_domaininfo); - set_to_dummy_if_null(ops, setvcpucontext); - set_to_dummy_if_null(ops, pausedomain); - set_to_dummy_if_null(ops, unpausedomain); - set_to_dummy_if_null(ops, resumedomain); set_to_dummy_if_null(ops, domain_create); - set_to_dummy_if_null(ops, max_vcpus); - set_to_dummy_if_null(ops, destroydomain); - set_to_dummy_if_null(ops, vcpuaffinity); - set_to_dummy_if_null(ops, scheduler); set_to_dummy_if_null(ops, getdomaininfo); - set_to_dummy_if_null(ops, getvcpucontext); - set_to_dummy_if_null(ops, getvcpuinfo); - set_to_dummy_if_null(ops, domain_settime); set_to_dummy_if_null(ops, set_target); set_to_dummy_if_null(ops, domctl); set_to_dummy_if_null(ops, sysctl); - set_to_dummy_if_null(ops, set_virq_handler); set_to_dummy_if_null(ops, tbufcontrol); set_to_dummy_if_null(ops, readconsole); set_to_dummy_if_null(ops, sched_id); - set_to_dummy_if_null(ops, setdomainmaxmem); - set_to_dummy_if_null(ops, setdomainhandle); - set_to_dummy_if_null(ops, setdebugging); set_to_dummy_if_null(ops, perfcontrol); set_to_dummy_if_null(ops, debug_keys); set_to_dummy_if_null(ops, getcpuinfo); @@ -126,21 +111,13 @@ void xsm_fixup_ops (struct xsm_operations *ops) #ifdef CONFIG_X86 set_to_dummy_if_null(ops, shadow_control); - set_to_dummy_if_null(ops, getpageframeinfo); - set_to_dummy_if_null(ops, getmemlist); - set_to_dummy_if_null(ops, hypercall_init); - set_to_dummy_if_null(ops, hvmcontext); - set_to_dummy_if_null(ops, address_size); - set_to_dummy_if_null(ops, machine_address_size); set_to_dummy_if_null(ops, hvm_param); set_to_dummy_if_null(ops, hvm_set_pci_intx_level); set_to_dummy_if_null(ops, hvm_set_isa_irq_level); set_to_dummy_if_null(ops, hvm_set_pci_link_route); set_to_dummy_if_null(ops, hvm_inject_msi); - set_to_dummy_if_null(ops, mem_event_setup); set_to_dummy_if_null(ops, mem_event_control); set_to_dummy_if_null(ops, mem_event_op); - set_to_dummy_if_null(ops, mem_sharing); set_to_dummy_if_null(ops, mem_sharing_op); set_to_dummy_if_null(ops, apic); set_to_dummy_if_null(ops, xen_settime); @@ -161,12 +138,8 @@ void xsm_fixup_ops (struct xsm_operations *ops) set_to_dummy_if_null(ops, update_va_mapping); set_to_dummy_if_null(ops, add_to_physmap); set_to_dummy_if_null(ops, remove_from_physmap); - set_to_dummy_if_null(ops, sendtrigger); set_to_dummy_if_null(ops, bind_pt_irq); set_to_dummy_if_null(ops, unbind_pt_irq); - set_to_dummy_if_null(ops, pin_mem_cacheattr); - set_to_dummy_if_null(ops, ext_vcpucontext); - set_to_dummy_if_null(ops, vcpuextstate); set_to_dummy_if_null(ops, ioport_permission); set_to_dummy_if_null(ops, ioport_mapping); #endif diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index 7707ac2..d137146 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -484,26 +484,6 @@ static void flask_security_domaininfo(struct domain *d, info->ssidref = domain_sid(d); } -static int flask_setvcpucontext(struct domain *d) -{ - return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETVCPUCONTEXT); -} - -static int flask_pausedomain(struct domain *d) -{ - return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__PAUSE); -} - -static int flask_unpausedomain(struct domain *d) -{ - return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__UNPAUSE); -} - -static int flask_resumedomain(struct domain *d) -{ - return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__RESUME); -} - static int flask_domain_create(struct domain *d, u32 ssidref) { int rc; @@ -532,66 +512,11 @@ static int flask_domain_create(struct domain *d, u32 ssidref) return rc; } -static int flask_max_vcpus(struct domain *d) -{ - return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__MAX_VCPUS); -} - -static int flask_destroydomain(struct domain *d) -{ - return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__DESTROY); -} - -static int flask_vcpuaffinity(int cmd, struct domain *d) -{ - u32 perm; - - switch ( cmd ) - { - case XEN_DOMCTL_setvcpuaffinity: - perm = DOMAIN__SETVCPUAFFINITY; - break; - case XEN_DOMCTL_getvcpuaffinity: - perm = DOMAIN__GETVCPUAFFINITY; - break; - default: - return -EPERM; - } - - return current_has_perm(d, SECCLASS_DOMAIN, perm ); -} - -static int flask_scheduler(struct domain *d) -{ - int rc = 0; - - rc = domain_has_xen(current->domain, XEN__SCHEDULER); - if ( rc ) - return rc; - - return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SCHEDULER); -} - static int flask_getdomaininfo(struct domain *d) { return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETDOMAININFO); } -static int flask_getvcpucontext(struct domain *d) -{ - return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETVCPUCONTEXT); -} - -static int flask_getvcpuinfo(struct domain *d) -{ - return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETVCPUINFO); -} - -static int flask_domain_settime(struct domain *d) -{ - return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETTIME); -} - static int flask_set_target(struct domain *d, struct domain *t) { int rc; @@ -622,62 +547,121 @@ static int flask_domctl(struct domain *d, int cmd) { /* These have individual XSM hooks (common/domctl.c) */ case XEN_DOMCTL_createdomain: + case XEN_DOMCTL_getdomaininfo: + case XEN_DOMCTL_irq_permission: + case XEN_DOMCTL_iomem_permission: + case XEN_DOMCTL_set_target: +#ifdef CONFIG_X86 + /* These have individual XSM hooks (arch/x86/domctl.c) */ + case XEN_DOMCTL_shadow_op: + case XEN_DOMCTL_ioport_permission: + case XEN_DOMCTL_bind_pt_irq: + case XEN_DOMCTL_unbind_pt_irq: + case XEN_DOMCTL_memory_mapping: + case XEN_DOMCTL_ioport_mapping: + case XEN_DOMCTL_mem_event_op: + /* These have individual XSM hooks (drivers/passthrough/iommu.c) */ + case XEN_DOMCTL_get_device_group: + case XEN_DOMCTL_test_assign_device: + case XEN_DOMCTL_assign_device: + case XEN_DOMCTL_deassign_device: +#endif + return 0; + case XEN_DOMCTL_destroydomain: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__DESTROY); + case XEN_DOMCTL_pausedomain: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__PAUSE); + case XEN_DOMCTL_unpausedomain: - case XEN_DOMCTL_getdomaininfo: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__UNPAUSE); + case XEN_DOMCTL_setvcpuaffinity: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETVCPUAFFINITY); + + case XEN_DOMCTL_getvcpuaffinity: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETVCPUAFFINITY); + + case XEN_DOMCTL_resumedomain: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__RESUME); + + case XEN_DOMCTL_scheduler_op: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SCHEDULER); + + case XEN_DOMCTL_max_vcpus: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__MAX_VCPUS); + case XEN_DOMCTL_max_mem: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETDOMAINMAXMEM); + + case XEN_DOMCTL_setdomainhandle: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETDOMAINHANDLE); + case XEN_DOMCTL_setvcpucontext: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETVCPUCONTEXT); + case XEN_DOMCTL_getvcpucontext: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETVCPUCONTEXT); + case XEN_DOMCTL_getvcpuinfo: - case XEN_DOMCTL_max_vcpus: - case XEN_DOMCTL_scheduler_op: - case XEN_DOMCTL_setdomainhandle: - case XEN_DOMCTL_setdebugging: - case XEN_DOMCTL_irq_permission: - case XEN_DOMCTL_iomem_permission: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETVCPUINFO); + case XEN_DOMCTL_settimeoffset: - case XEN_DOMCTL_getvcpuaffinity: - case XEN_DOMCTL_resumedomain: - case XEN_DOMCTL_set_target: - case XEN_DOMCTL_set_virq_handler: -#ifdef CONFIG_X86 - /* These have individual XSM hooks (arch/x86/domctl.c) */ - case XEN_DOMCTL_shadow_op: - case XEN_DOMCTL_ioport_permission: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETTIME); + + case XEN_DOMCTL_setdebugging: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETDEBUGGING); + case XEN_DOMCTL_getpageframeinfo: case XEN_DOMCTL_getpageframeinfo2: case XEN_DOMCTL_getpageframeinfo3: + return current_has_perm(d, SECCLASS_MMU, MMU__PAGEINFO); + case XEN_DOMCTL_getmemlist: + return current_has_perm(d, SECCLASS_MMU, MMU__PAGELIST); + case XEN_DOMCTL_hypercall_init: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__HYPERCALL); + case XEN_DOMCTL_sethvmcontext: + return current_has_perm(d, SECCLASS_HVM, HVM__SETHVMC); + case XEN_DOMCTL_gethvmcontext: case XEN_DOMCTL_gethvmcontext_partial: + return current_has_perm(d, SECCLASS_HVM, HVM__GETHVMC); + case XEN_DOMCTL_set_address_size: - case XEN_DOMCTL_get_address_size: case XEN_DOMCTL_set_machine_address_size: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETADDRSIZE); + + case XEN_DOMCTL_get_address_size: case XEN_DOMCTL_get_machine_address_size: - case XEN_DOMCTL_sendtrigger: - case XEN_DOMCTL_bind_pt_irq: - case XEN_DOMCTL_unbind_pt_irq: - case XEN_DOMCTL_memory_mapping: - case XEN_DOMCTL_ioport_mapping: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETADDRSIZE); + + case XEN_DOMCTL_mem_sharing_op: + return current_has_perm(d, SECCLASS_HVM, HVM__MEM_SHARING); + case XEN_DOMCTL_pin_mem_cacheattr: + return current_has_perm(d, SECCLASS_HVM, HVM__CACHEATTR); + case XEN_DOMCTL_set_ext_vcpucontext: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETEXTVCPUCONTEXT); + case XEN_DOMCTL_get_ext_vcpucontext: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETEXTVCPUCONTEXT); + case XEN_DOMCTL_setvcpuextstate: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETVCPUEXTSTATE); + case XEN_DOMCTL_getvcpuextstate: - case XEN_DOMCTL_mem_event_op: - case XEN_DOMCTL_mem_sharing_op: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETVCPUEXTSTATE); + + case XEN_DOMCTL_sendtrigger: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__TRIGGER); + case XEN_DOMCTL_set_access_required: - /* These have individual XSM hooks (drivers/passthrough/iommu.c) */ - case XEN_DOMCTL_get_device_group: - case XEN_DOMCTL_test_assign_device: - case XEN_DOMCTL_assign_device: - case XEN_DOMCTL_deassign_device: -#endif - return 0; + return current_has_perm(d, SECCLASS_HVM, HVM__MEM_EVENT); case XEN_DOMCTL_debug_op: case XEN_DOMCTL_gdbsx_guestmemio: @@ -691,6 +675,9 @@ static int flask_domctl(struct domain *d, int cmd) case XEN_DOMCTL_suppress_spurious_page_faults: return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SET_MISC_INFO); + case XEN_DOMCTL_set_virq_handler: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SET_VIRQ_HANDLER); + case XEN_DOMCTL_set_cpuid: return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__SET_CPUID); @@ -741,11 +728,6 @@ static int flask_sysctl(int cmd) } } -static int flask_set_virq_handler(struct domain *d, uint32_t virq) -{ - return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SET_VIRQ_HANDLER); -} - static int flask_tbufcontrol(void) { return domain_has_xen(current->domain, XEN__TBUFCONTROL); @@ -766,21 +748,6 @@ static int flask_sched_id(void) return domain_has_xen(current->domain, XEN__SCHEDULER); } -static int flask_setdomainmaxmem(struct domain *d) -{ - return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETDOMAINMAXMEM); -} - -static int flask_setdomainhandle(struct domain *d) -{ - return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETDOMAINHANDLE); -} - -static int flask_setdebugging(struct domain *d) -{ - return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETDEBUGGING); -} - static int flask_debug_keys(void) { return domain_has_xen(current->domain, XEN__DEBUG); @@ -1165,82 +1132,6 @@ static int flask_ioport_mapping(struct domain *d, uint32_t start, uint32_t end, return flask_ioport_permission(d, start, end, access); } -static int flask_getpageframeinfo(struct domain *d) -{ - return current_has_perm(d, SECCLASS_MMU, MMU__PAGEINFO); -} - -static int flask_getmemlist(struct domain *d) -{ - return current_has_perm(d, SECCLASS_MMU, MMU__PAGELIST); -} - -static int flask_hypercall_init(struct domain *d) -{ - return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__HYPERCALL); -} - -static int flask_hvmcontext(struct domain *d, uint32_t cmd) -{ - u32 perm; - - switch ( cmd ) - { - case XEN_DOMCTL_sethvmcontext: - perm = HVM__SETHVMC; - break; - case XEN_DOMCTL_gethvmcontext: - case XEN_DOMCTL_gethvmcontext_partial: - perm = HVM__GETHVMC; - break; - case HVMOP_track_dirty_vram: - perm = HVM__TRACKDIRTYVRAM; - break; - default: - return -EPERM; - } - - return current_has_perm(d, SECCLASS_HVM, perm); -} - -static int flask_address_size(struct domain *d, uint32_t cmd) -{ - u32 perm; - - switch ( cmd ) - { - case XEN_DOMCTL_set_address_size: - perm = DOMAIN__SETADDRSIZE; - break; - case XEN_DOMCTL_get_address_size: - perm = DOMAIN__GETADDRSIZE; - break; - default: - return -EPERM; - } - - return current_has_perm(d, SECCLASS_DOMAIN, perm); -} - -static int flask_machine_address_size(struct domain *d, uint32_t cmd) -{ - u32 perm; - - switch ( cmd ) - { - case XEN_DOMCTL_set_machine_address_size: - perm = DOMAIN__SETADDRSIZE; - break; - case XEN_DOMCTL_get_machine_address_size: - perm = DOMAIN__GETADDRSIZE; - break; - default: - return -EPERM; - } - - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, perm); -} - static int flask_hvm_param(struct domain *d, unsigned long op) { u32 perm; @@ -1283,11 +1174,6 @@ static int flask_hvm_inject_msi(struct domain *d) return current_has_perm(d, SECCLASS_HVM, HVM__SEND_IRQ); } -static int flask_mem_event_setup(struct domain *d) -{ - return current_has_perm(d, SECCLASS_HVM, HVM__MEM_EVENT); -} - static int flask_mem_event_control(struct domain *d, int mode, int op) { return current_has_perm(d, SECCLASS_HVM, HVM__MEM_EVENT); @@ -1298,11 +1184,6 @@ static int flask_mem_event_op(struct domain *d, int op) return current_has_perm(d, SECCLASS_HVM, HVM__MEM_EVENT); } -static int flask_mem_sharing(struct domain *d) -{ - return current_has_perm(d, SECCLASS_HVM, HVM__MEM_SHARING); -} - static int flask_mem_sharing_op(struct domain *d, struct domain *cd, int op) { int rc = current_has_perm(cd, SECCLASS_HVM, HVM__MEM_SHARING); @@ -1490,11 +1371,6 @@ static int flask_remove_from_physmap(struct domain *d1, struct domain *d2) return domain_has_perm(d1, d2, SECCLASS_MMU, MMU__PHYSMAP); } -static int flask_sendtrigger(struct domain *d) -{ - return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__TRIGGER); -} - static int flask_get_device_group(uint32_t machine_bdf) { u32 rsid; @@ -1588,78 +1464,20 @@ static int flask_unbind_pt_irq (struct domain *d, struct xen_domctl_bind_pt_irq { return current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__REMOVE); } - -static int flask_pin_mem_cacheattr (struct domain *d) -{ - return current_has_perm(d, SECCLASS_HVM, HVM__CACHEATTR); -} - -static int flask_ext_vcpucontext (struct domain *d, uint32_t cmd) -{ - u32 perm; - - switch ( cmd ) - { - case XEN_DOMCTL_set_ext_vcpucontext: - perm = DOMAIN__SETEXTVCPUCONTEXT; - break; - case XEN_DOMCTL_get_ext_vcpucontext: - perm = DOMAIN__GETEXTVCPUCONTEXT; - break; - default: - return -EPERM; - } - - return current_has_perm(d, SECCLASS_DOMAIN, perm); -} - -static int flask_vcpuextstate (struct domain *d, uint32_t cmd) -{ - u32 perm; - - switch ( cmd ) - { - case XEN_DOMCTL_setvcpuextstate: - perm = DOMAIN__SETVCPUEXTSTATE; - break; - case XEN_DOMCTL_getvcpuextstate: - perm = DOMAIN__GETVCPUEXTSTATE; - break; - default: - return -EPERM; - } - - return current_has_perm(d, SECCLASS_DOMAIN, perm); -} #endif long do_flask_op(XEN_GUEST_HANDLE_PARAM(xsm_op_t) u_flask_op); static struct xsm_operations flask_ops = { .security_domaininfo = flask_security_domaininfo, - .setvcpucontext = flask_setvcpucontext, - .pausedomain = flask_pausedomain, - .unpausedomain = flask_unpausedomain, - .resumedomain = flask_resumedomain, .domain_create = flask_domain_create, - .max_vcpus = flask_max_vcpus, - .destroydomain = flask_destroydomain, - .vcpuaffinity = flask_vcpuaffinity, - .scheduler = flask_scheduler, .getdomaininfo = flask_getdomaininfo, - .getvcpucontext = flask_getvcpucontext, - .getvcpuinfo = flask_getvcpuinfo, - .domain_settime = flask_domain_settime, .set_target = flask_set_target, .domctl = flask_domctl, .sysctl = flask_sysctl, - .set_virq_handler = flask_set_virq_handler, .tbufcontrol = flask_tbufcontrol, .readconsole = flask_readconsole, .sched_id = flask_sched_id, - .setdomainmaxmem = flask_setdomainmaxmem, - .setdomainhandle = flask_setdomainhandle, - .setdebugging = flask_setdebugging, .perfcontrol = flask_perfcontrol, .debug_keys = flask_debug_keys, .getcpuinfo = flask_getcpuinfo, @@ -1729,21 +1547,13 @@ static struct xsm_operations flask_ops = { #ifdef CONFIG_X86 .shadow_control = flask_shadow_control, - .getpageframeinfo = flask_getpageframeinfo, - .getmemlist = flask_getmemlist, - .hypercall_init = flask_hypercall_init, - .hvmcontext = flask_hvmcontext, - .address_size = flask_address_size, - .machine_address_size = flask_machine_address_size, .hvm_param = flask_hvm_param, .hvm_set_pci_intx_level = flask_hvm_set_pci_intx_level, .hvm_set_isa_irq_level = flask_hvm_set_isa_irq_level, .hvm_set_pci_link_route = flask_hvm_set_pci_link_route, .hvm_inject_msi = flask_hvm_inject_msi, - .mem_event_setup = flask_mem_event_setup, .mem_event_control = flask_mem_event_control, .mem_event_op = flask_mem_event_op, - .mem_sharing = flask_mem_sharing, .mem_sharing_op = flask_mem_sharing_op, .apic = flask_apic, .xen_settime = flask_xen_settime, @@ -1764,16 +1574,12 @@ static struct xsm_operations flask_ops = { .update_va_mapping = flask_update_va_mapping, .add_to_physmap = flask_add_to_physmap, .remove_from_physmap = flask_remove_from_physmap, - .sendtrigger = flask_sendtrigger, .get_device_group = flask_get_device_group, .test_assign_device = flask_test_assign_device, .assign_device = flask_assign_device, .deassign_device = flask_deassign_device, .bind_pt_irq = flask_bind_pt_irq, .unbind_pt_irq = flask_unbind_pt_irq, - .pin_mem_cacheattr = flask_pin_mem_cacheattr, - .ext_vcpucontext = flask_ext_vcpucontext, - .vcpuextstate = flask_vcpuextstate, .ioport_permission = flask_ioport_permission, .ioport_mapping = flask_ioport_mapping, #endif -- 1.7.11.7
A number of the sysctl XSM hooks have no parameters or only pass the operation ID, making them redundant with the xsm_sysctl hook. Remove these redundant hooks. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Cc: Keir Fraser <keir@xen.org> Cc: Jan Beulich <jbeulich@suse.com> --- xen/arch/x86/sysctl.c | 13 ----- xen/common/sysctl.c | 44 ----------------- xen/include/xsm/dummy.h | 50 ------------------- xen/include/xsm/xsm.h | 62 +----------------------- xen/xsm/dummy.c | 10 ---- xen/xsm/flask/hooks.c | 125 +++++++++++++++--------------------------------- 6 files changed, 39 insertions(+), 265 deletions(-) diff --git a/xen/arch/x86/sysctl.c b/xen/arch/x86/sysctl.c index 8f1c4be..59e8100 100644 --- a/xen/arch/x86/sysctl.c +++ b/xen/arch/x86/sysctl.c @@ -69,11 +69,6 @@ long arch_do_sysctl( { xen_sysctl_physinfo_t *pi = &sysctl->u.physinfo; - ret = xsm_physinfo(); - if ( ret ) - break; - - memset(pi, 0, sizeof(*pi)); pi->threads_per_core cpumask_weight(per_cpu(cpu_sibling_mask, 0)); @@ -103,10 +98,6 @@ long arch_do_sysctl( uint32_t i, max_cpu_index, last_online_cpu; xen_sysctl_topologyinfo_t *ti = &sysctl->u.topologyinfo; - ret = xsm_physinfo(); - if ( ret ) - break; - last_online_cpu = cpumask_last(&cpu_online_map); max_cpu_index = min_t(uint32_t, ti->max_cpu_index, last_online_cpu); ti->max_cpu_index = last_online_cpu; @@ -144,10 +135,6 @@ long arch_do_sysctl( uint32_t i, j, max_node_index, last_online_node; xen_sysctl_numainfo_t *ni = &sysctl->u.numainfo; - ret = xsm_physinfo(); - if ( ret ) - break; - last_online_node = last_node(node_online_map); max_node_index = min_t(uint32_t, ni->max_node_index, last_online_node); ni->max_node_index = last_online_node; diff --git a/xen/common/sysctl.c b/xen/common/sysctl.c index 61e7a29..2ebf5e6 100644 --- a/xen/common/sysctl.c +++ b/xen/common/sysctl.c @@ -65,18 +65,10 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl) break; case XEN_SYSCTL_tbuf_op: - ret = xsm_tbufcontrol(); - if ( ret ) - break; - ret = tb_control(&op->u.tbuf_op); break; case XEN_SYSCTL_sched_id: - ret = xsm_sched_id(); - if ( ret ) - break; - op->u.sched_id.sched_id = sched_id(); break; @@ -122,20 +114,12 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl) #ifdef PERF_COUNTERS case XEN_SYSCTL_perfc_op: - ret = xsm_perfcontrol(); - if ( ret ) - break; - ret = perfc_control(&op->u.perfc_op); break; #endif #ifdef LOCK_PROFILE case XEN_SYSCTL_lockprof_op: - ret = xsm_lockprof(); - if ( ret ) - break; - ret = spinlock_profile_control(&op->u.lockprof_op); break; #endif @@ -144,10 +128,6 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl) char c; uint32_t i; - ret = xsm_debug_keys(); - if ( ret ) - break; - ret = -EFAULT; for ( i = 0; i < op->u.debug_keys.nr_keys; i++ ) { @@ -167,10 +147,6 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl) nr_cpus = min(op->u.getcpuinfo.max_cpus, nr_cpu_ids); - ret = xsm_getcpuinfo(); - if ( ret ) - break; - ret = -EFAULT; for ( i = 0; i < nr_cpus; i++ ) { @@ -186,10 +162,6 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl) break; case XEN_SYSCTL_availheap: - ret = xsm_availheap(); - if ( ret ) - break; - op->u.availheap.avail_bytes = avail_domheap_pages_region( op->u.availheap.node, op->u.availheap.min_bitwidth, @@ -199,18 +171,10 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl) #ifdef HAS_ACPI case XEN_SYSCTL_get_pmstat: - ret = xsm_get_pmstat(); - if ( ret ) - break; - ret = do_get_pm_info(&op->u.get_pmstat); break; case XEN_SYSCTL_pm_op: - ret = xsm_pm_op(); - if ( ret ) - break; - ret = do_pm_op(&op->u.pm_op); if ( ret == -EAGAIN ) copyback = 1; @@ -278,18 +242,10 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl) break; case XEN_SYSCTL_cpupool_op: - ret = xsm_cpupool_op(); - if ( ret ) - break; - ret = cpupool_do_sysctl(&op->u.cpupool_op); break; case XEN_SYSCTL_scheduler_op: - ret = xsm_sched_op(); - if ( ret ) - break; - ret = sched_adjust_global(&op->u.scheduler_op); break; diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index 2b18f51..64124a8 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -58,41 +58,16 @@ static XSM_INLINE int xsm_sysctl(int cmd) return 0; } -static XSM_INLINE int xsm_tbufcontrol(void) -{ - return 0; -} - static XSM_INLINE int xsm_readconsole(uint32_t clear) { return 0; } -static XSM_INLINE int xsm_sched_id(void) -{ - return 0; -} - -static XSM_INLINE int xsm_perfcontrol(void) -{ - return 0; -} - -static XSM_INLINE int xsm_debug_keys(void) -{ - return 0; -} - static XSM_INLINE int xsm_getcpuinfo(void) { return 0; } -static XSM_INLINE int xsm_get_pmstat(void) -{ - return 0; -} - static XSM_INLINE int xsm_setpminfo(void) { return 0; @@ -110,11 +85,6 @@ static XSM_INLINE int xsm_do_mca(void) return 0; } -static XSM_INLINE int xsm_availheap(void) -{ - return 0; -} - static XSM_INLINE int xsm_alloc_security_domain(struct domain *d) { return 0; @@ -353,21 +323,6 @@ static XSM_INLINE int xsm_page_offline(uint32_t cmd) return 0; } -static XSM_INLINE int xsm_lockprof(void) -{ - return 0; -} - -static XSM_INLINE int xsm_cpupool_op(void) -{ - return 0; -} - -static XSM_INLINE int xsm_sched_op(void) -{ - return 0; -} - static XSM_INLINE long xsm_do_xsm_op(XEN_GUEST_HANDLE_PARAM(xsm_op_t) op) { return -ENOSYS; @@ -496,11 +451,6 @@ static XSM_INLINE int xsm_microcode(void) return 0; } -static XSM_INLINE int xsm_physinfo(void) -{ - return 0; -} - static XSM_INLINE int xsm_platform_quirk(uint32_t quirk) { return 0; diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index 4676c75..5eeaced 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -46,14 +46,8 @@ struct xsm_operations { int (*set_target) (struct domain *d, struct domain *e); int (*domctl) (struct domain *d, int cmd); int (*sysctl) (int cmd); - int (*tbufcontrol) (void); int (*readconsole) (uint32_t clear); - int (*sched_id) (void); - int (*perfcontrol) (void); - int (*debug_keys) (void); int (*getcpuinfo) (void); - int (*availheap) (void); - int (*get_pmstat) (void); int (*setpminfo) (void); int (*pm_op) (void); int (*do_mca) (void); @@ -116,9 +110,6 @@ struct xsm_operations { int (*resource_setup_misc) (void); int (*page_offline)(uint32_t cmd); - int (*lockprof)(void); - int (*cpupool_op)(void); - int (*sched_op)(void); long (*do_xsm_op) (XEN_GUEST_HANDLE_PARAM(xsm_op_t) op); @@ -136,7 +127,6 @@ struct xsm_operations { int (*xen_settime) (void); int (*memtype) (uint32_t access); int (*microcode) (void); - int (*physinfo) (void); int (*platform_quirk) (uint32_t); int (*platform_op) (uint32_t cmd); int (*firmware_info) (void); @@ -199,46 +189,16 @@ static inline int xsm_sysctl (int cmd) return xsm_ops->sysctl(cmd); } -static inline int xsm_tbufcontrol (void) -{ - return xsm_ops->tbufcontrol(); -} - static inline int xsm_readconsole (uint32_t clear) { return xsm_ops->readconsole(clear); } -static inline int xsm_sched_id (void) -{ - return xsm_ops->sched_id(); -} - -static inline int xsm_perfcontrol (void) -{ - return xsm_ops->perfcontrol(); -} - -static inline int xsm_debug_keys (void) -{ - return xsm_ops->debug_keys(); -} - -static inline int xsm_availheap (void) -{ - return xsm_ops->availheap(); -} - -static inline int xsm_getcpuinfo (void) +static inline int xsm_getcpuinfo(void) { return xsm_ops->getcpuinfo(); } -static inline int xsm_get_pmstat(void) -{ - return xsm_ops->get_pmstat(); -} - static inline int xsm_setpminfo(void) { return xsm_ops->setpminfo(); @@ -495,21 +455,6 @@ static inline int xsm_page_offline(uint32_t cmd) return xsm_ops->page_offline(cmd); } -static inline int xsm_lockprof(void) -{ - return xsm_ops->lockprof(); -} - -static inline int xsm_cpupool_op(void) -{ - return xsm_ops->cpupool_op(); -} - -static inline int xsm_sched_op(void) -{ - return xsm_ops->sched_op(); -} - static inline long xsm_do_xsm_op (XEN_GUEST_HANDLE_PARAM(xsm_op_t) op) { return xsm_ops->do_xsm_op(op); @@ -581,11 +526,6 @@ static inline int xsm_microcode (void) return xsm_ops->microcode(); } -static inline int xsm_physinfo (void) -{ - return xsm_ops->physinfo(); -} - static inline int xsm_platform_quirk (uint32_t quirk) { return xsm_ops->platform_quirk(quirk); diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c index a14a755..131a230 100644 --- a/xen/xsm/dummy.c +++ b/xen/xsm/dummy.c @@ -35,14 +35,8 @@ void xsm_fixup_ops (struct xsm_operations *ops) set_to_dummy_if_null(ops, set_target); set_to_dummy_if_null(ops, domctl); set_to_dummy_if_null(ops, sysctl); - set_to_dummy_if_null(ops, tbufcontrol); set_to_dummy_if_null(ops, readconsole); - set_to_dummy_if_null(ops, sched_id); - set_to_dummy_if_null(ops, perfcontrol); - set_to_dummy_if_null(ops, debug_keys); set_to_dummy_if_null(ops, getcpuinfo); - set_to_dummy_if_null(ops, availheap); - set_to_dummy_if_null(ops, get_pmstat); set_to_dummy_if_null(ops, setpminfo); set_to_dummy_if_null(ops, pm_op); set_to_dummy_if_null(ops, do_mca); @@ -103,9 +97,6 @@ void xsm_fixup_ops (struct xsm_operations *ops) set_to_dummy_if_null(ops, resource_setup_misc); set_to_dummy_if_null(ops, page_offline); - set_to_dummy_if_null(ops, lockprof); - set_to_dummy_if_null(ops, cpupool_op); - set_to_dummy_if_null(ops, sched_op); set_to_dummy_if_null(ops, do_xsm_op); @@ -123,7 +114,6 @@ void xsm_fixup_ops (struct xsm_operations *ops) set_to_dummy_if_null(ops, xen_settime); set_to_dummy_if_null(ops, memtype); set_to_dummy_if_null(ops, microcode); - set_to_dummy_if_null(ops, physinfo); set_to_dummy_if_null(ops, platform_quirk); set_to_dummy_if_null(ops, platform_op); set_to_dummy_if_null(ops, firmware_info); diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index d137146..a8bfddd 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -702,37 +702,57 @@ static int flask_sysctl(int cmd) { /* These have individual XSM hooks */ case XEN_SYSCTL_readconsole: + case XEN_SYSCTL_getdomaininfolist: + case XEN_SYSCTL_page_offline_op: +#ifdef CONFIG_X86 + case XEN_SYSCTL_cpu_hotplug: +#endif + return 0; + case XEN_SYSCTL_tbuf_op: + return domain_has_xen(current->domain, XEN__TBUFCONTROL); + case XEN_SYSCTL_sched_id: + return domain_has_xen(current->domain, XEN__SCHEDULER); + case XEN_SYSCTL_perfc_op: - case XEN_SYSCTL_getdomaininfolist: + return domain_has_xen(current->domain, XEN__PERFCONTROL); + case XEN_SYSCTL_debug_keys: + return domain_has_xen(current->domain, XEN__DEBUG); + case XEN_SYSCTL_getcpuinfo: + return domain_has_xen(current->domain, XEN__GETCPUINFO); + case XEN_SYSCTL_availheap: + return domain_has_xen(current->domain, XEN__HEAP); + case XEN_SYSCTL_get_pmstat: + return domain_has_xen(current->domain, XEN__PM_OP); + case XEN_SYSCTL_pm_op: - case XEN_SYSCTL_page_offline_op: + return domain_has_xen(current->domain, XEN__PM_OP); + case XEN_SYSCTL_lockprof_op: + return domain_has_xen(current->domain, XEN__LOCKPROF); + case XEN_SYSCTL_cpupool_op: + return domain_has_xen(current->domain, XEN__CPUPOOL_OP); + case XEN_SYSCTL_scheduler_op: -#ifdef CONFIG_X86 + return domain_has_xen(current->domain, XEN__SCHED_OP); + case XEN_SYSCTL_physinfo: - case XEN_SYSCTL_cpu_hotplug: case XEN_SYSCTL_topologyinfo: case XEN_SYSCTL_numainfo: -#endif - return 0; + return domain_has_xen(current->domain, XEN__PHYSINFO); + default: printk("flask_sysctl: Unknown op %d\n", cmd); return -EPERM; } } -static int flask_tbufcontrol(void) -{ - return domain_has_xen(current->domain, XEN__TBUFCONTROL); -} - static int flask_readconsole(uint32_t clear) { u32 perms = XEN__READCONSOLE; @@ -743,41 +763,6 @@ static int flask_readconsole(uint32_t clear) return domain_has_xen(current->domain, perms); } -static int flask_sched_id(void) -{ - return domain_has_xen(current->domain, XEN__SCHEDULER); -} - -static int flask_debug_keys(void) -{ - return domain_has_xen(current->domain, XEN__DEBUG); -} - -static int flask_getcpuinfo(void) -{ - return domain_has_xen(current->domain, XEN__GETCPUINFO); -} - -static int flask_availheap(void) -{ - return domain_has_xen(current->domain, XEN__HEAP); -} - -static int flask_get_pmstat(void) -{ - return domain_has_xen(current->domain, XEN__PM_OP); -} - -static int flask_setpminfo(void) -{ - return domain_has_xen(current->domain, XEN__PM_OP); -} - -static int flask_pm_op(void) -{ - return domain_has_xen(current->domain, XEN__PM_OP); -} - static int flask_do_mca(void) { return domain_has_xen(current->domain, XEN__MCA_OP); @@ -1032,26 +1017,6 @@ static inline int flask_page_offline(uint32_t cmd) } } -static inline int flask_lockprof(void) -{ - return domain_has_xen(current->domain, XEN__LOCKPROF); -} - -static inline int flask_cpupool_op(void) -{ - return domain_has_xen(current->domain, XEN__CPUPOOL_OP); -} - -static inline int flask_sched_op(void) -{ - return domain_has_xen(current->domain, XEN__SCHED_OP); -} - -static int flask_perfcontrol(void) -{ - return domain_has_xen(current->domain, XEN__PERFCONTROL); -} - #ifdef CONFIG_X86 static int flask_shadow_control(struct domain *d, uint32_t op) { @@ -1244,11 +1209,6 @@ static int flask_microcode(void) return domain_has_xen(current->domain, XEN__MICROCODE); } -static int flask_physinfo(void) -{ - return domain_has_xen(current->domain, XEN__PHYSINFO); -} - static int flask_platform_quirk(uint32_t quirk) { return avc_current_has_perm(SECINITSID_XEN, SECCLASS_XEN, XEN__QUIRK, NULL); @@ -1269,17 +1229,21 @@ static int flask_platform_op(uint32_t op) case XENPF_enter_acpi_sleep: case XENPF_change_freq: case XENPF_getidletime: - case XENPF_set_processor_pminfo: - case XENPF_get_cpuinfo: - case XENPF_get_cpu_version: case XENPF_cpu_online: case XENPF_cpu_offline: case XENPF_cpu_hotadd: case XENPF_mem_hotadd: /* These operations have their own XSM hooks */ return 0; + + case XENPF_set_processor_pminfo: case XENPF_core_parking: return domain_has_xen(current->domain, XEN__PM_OP); + + case XENPF_get_cpu_version: + case XENPF_get_cpuinfo: + return domain_has_xen(current->domain, XEN__GETCPUINFO); + default: printk("flask_platform_op: Unknown op %d\n", op); return -EPERM; @@ -1475,16 +1439,7 @@ static struct xsm_operations flask_ops = { .set_target = flask_set_target, .domctl = flask_domctl, .sysctl = flask_sysctl, - .tbufcontrol = flask_tbufcontrol, .readconsole = flask_readconsole, - .sched_id = flask_sched_id, - .perfcontrol = flask_perfcontrol, - .debug_keys = flask_debug_keys, - .getcpuinfo = flask_getcpuinfo, - .availheap = flask_availheap, - .get_pmstat = flask_get_pmstat, - .setpminfo = flask_setpminfo, - .pm_op = flask_pm_op, .do_mca = flask_do_mca, .evtchn_unbound = flask_evtchn_unbound, @@ -1539,9 +1494,6 @@ static struct xsm_operations flask_ops = { .resource_setup_misc = flask_resource_setup_misc, .page_offline = flask_page_offline, - .lockprof = flask_lockprof, - .cpupool_op = flask_cpupool_op, - .sched_op = flask_sched_op, .do_xsm_op = do_flask_op, @@ -1559,7 +1511,6 @@ static struct xsm_operations flask_ops = { .xen_settime = flask_xen_settime, .memtype = flask_memtype, .microcode = flask_microcode, - .physinfo = flask_physinfo, .platform_quirk = flask_platform_quirk, .platform_op = flask_platform_op, .firmware_info = flask_firmware_info, -- 1.7.11.7
Daniel De Graaf
2013-Jan-10 15:33 UTC
[PATCH 17/22] xen: platform_hypercall XSM hook removal
A number of the platform_hypercall XSM hooks have no parameters or only pass the operation ID, making them redundant with the xsm_platform_op hook. Remove these redundant hooks. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Cc: Keir Fraser <keir@xen.org> Cc: Jan Beulich <jbeulich@suse.com> --- xen/arch/x86/platform_hypercall.c | 60 --------------------- xen/include/xsm/dummy.h | 62 ---------------------- xen/include/xsm/xsm.h | 66 ----------------------- xen/xsm/dummy.c | 12 ----- xen/xsm/flask/hooks.c | 107 +++++++++++--------------------------- 5 files changed, 30 insertions(+), 277 deletions(-) diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c index 570b3db..a67aff4 100644 --- a/xen/arch/x86/platform_hypercall.c +++ b/xen/arch/x86/platform_hypercall.c @@ -90,10 +90,6 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) { case XENPF_settime: { - ret = xsm_xen_settime(); - if ( ret ) - break; - do_settime(op->u.settime.secs, op->u.settime.nsecs, op->u.settime.system_time); @@ -103,10 +99,6 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) case XENPF_add_memtype: { - ret = xsm_memtype(op->cmd); - if ( ret ) - break; - ret = mtrr_add_page( op->u.add_memtype.mfn, op->u.add_memtype.nr_mfns, @@ -126,10 +118,6 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) case XENPF_del_memtype: { - ret = xsm_memtype(op->cmd); - if ( ret ) - break; - if (op->u.del_memtype.handle == 0 /* mtrr/main.c otherwise does a lookup */ && (int)op->u.del_memtype.reg >= 0) @@ -148,10 +136,6 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) unsigned long mfn, nr_mfns; mtrr_type type; - ret = xsm_memtype(op->cmd); - if ( ret ) - break; - ret = -EINVAL; if ( op->u.read_memtype.reg < num_var_ranges ) { @@ -169,10 +153,6 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) { XEN_GUEST_HANDLE(const_void) data; - ret = xsm_microcode(); - if ( ret ) - break; - guest_from_compat_handle(data, op->u.microcode.data); /* @@ -200,10 +180,6 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) { int quirk_id = op->u.platform_quirk.quirk_id; - ret = xsm_platform_quirk(quirk_id); - if ( ret ) - break; - switch ( quirk_id ) { case QUIRK_NOIRQBALANCING: @@ -225,10 +201,6 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) break; case XENPF_firmware_info: - ret = xsm_firmware_info(); - if ( ret ) - break; - switch ( op->u.firmware_info.type ) { case XEN_FW_DISK_INFO: { @@ -337,10 +309,6 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) break; case XENPF_efi_runtime_call: - ret = xsm_efi_call(); - if ( ret ) - break; - ret = efi_runtime_call(&op->u.efi_runtime_call); if ( ret == 0 && __copy_field_to_guest(u_xenpf_op, op, u.efi_runtime_call) ) @@ -348,18 +316,10 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) break; case XENPF_enter_acpi_sleep: - ret = xsm_acpi_sleep(); - if ( ret ) - break; - ret = acpi_enter_sleep(&op->u.enter_acpi_sleep); break; case XENPF_change_freq: - ret = xsm_change_freq(); - if ( ret ) - break; - ret = -ENOSYS; if ( cpufreq_controller != FREQCTL_dom0_kernel ) break; @@ -381,10 +341,6 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) XEN_GUEST_HANDLE(uint8) cpumap_bitmap; XEN_GUEST_HANDLE(uint64) idletimes; - ret = xsm_getidletime(); - if ( ret ) - break; - ret = -ENOSYS; if ( cpufreq_controller != FREQCTL_dom0_kernel ) break; @@ -421,10 +377,6 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) break; case XENPF_set_processor_pminfo: - ret = xsm_setpminfo(); - if ( ret ) - break; - switch ( op->u.set_pminfo.type ) { case XEN_PM_PX: @@ -477,10 +429,6 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) g_info = &op->u.pcpu_info; - ret = xsm_getcpuinfo(); - if ( ret ) - break; - if ( !get_cpu_maps() ) { ret = -EBUSY; @@ -514,10 +462,6 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) { struct xenpf_pcpu_version *ver = &op->u.pcpu_version; - ret = xsm_getcpuinfo(); - if ( ret ) - break; - if ( !get_cpu_maps() ) { ret = -EBUSY; @@ -570,10 +514,6 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) break; } - ret = xsm_resource_plug_core(); - if ( ret ) - break; - ret = continue_hypercall_on_cpu( 0, cpu_up_helper, (void *)(unsigned long)cpu); break; diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index 64124a8..721fcb4 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -63,21 +63,6 @@ static XSM_INLINE int xsm_readconsole(uint32_t clear) return 0; } -static XSM_INLINE int xsm_getcpuinfo(void) -{ - return 0; -} - -static XSM_INLINE int xsm_setpminfo(void) -{ - return 0; -} - -static XSM_INLINE int xsm_pm_op(void) -{ - return 0; -} - static XSM_INLINE int xsm_do_mca(void) { if ( !IS_PRIV(current->domain) ) @@ -436,26 +421,6 @@ static XSM_INLINE int xsm_apic(struct domain *d, int cmd) return 0; } -static XSM_INLINE int xsm_xen_settime(void) -{ - return 0; -} - -static XSM_INLINE int xsm_memtype(uint32_t access) -{ - return 0; -} - -static XSM_INLINE int xsm_microcode(void) -{ - return 0; -} - -static XSM_INLINE int xsm_platform_quirk(uint32_t quirk) -{ - return 0; -} - static XSM_INLINE int xsm_platform_op(uint32_t op) { if ( !IS_PRIV(current->domain) ) @@ -463,33 +428,6 @@ static XSM_INLINE int xsm_platform_op(uint32_t op) return 0; } -static XSM_INLINE int xsm_firmware_info(void) -{ - return 0; -} - -static XSM_INLINE int xsm_efi_call(void) -{ - return 0; -} - -static XSM_INLINE int xsm_acpi_sleep(void) -{ - if ( !IS_PRIV(current->domain) ) - return -EPERM; - return 0; -} - -static XSM_INLINE int xsm_change_freq(void) -{ - return 0; -} - -static XSM_INLINE int xsm_getidletime(void) -{ - return 0; -} - static XSM_INLINE int xsm_machine_memory_map(void) { if ( !IS_PRIV(current->domain) ) diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index 5eeaced..7b62d78 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -47,9 +47,6 @@ struct xsm_operations { int (*domctl) (struct domain *d, int cmd); int (*sysctl) (int cmd); int (*readconsole) (uint32_t clear); - int (*getcpuinfo) (void); - int (*setpminfo) (void); - int (*pm_op) (void); int (*do_mca) (void); int (*evtchn_unbound) (struct domain *d, struct evtchn *chn, domid_t id2); @@ -124,16 +121,8 @@ struct xsm_operations { int (*mem_event_op) (struct domain *d, int op); int (*mem_sharing_op) (struct domain *d, struct domain *cd, int op); int (*apic) (struct domain *d, int cmd); - int (*xen_settime) (void); int (*memtype) (uint32_t access); - int (*microcode) (void); - int (*platform_quirk) (uint32_t); int (*platform_op) (uint32_t cmd); - int (*firmware_info) (void); - int (*efi_call) (void); - int (*acpi_sleep) (void); - int (*change_freq) (void); - int (*getidletime) (void); int (*machine_memory_map) (void); int (*domain_memory_map) (struct domain *d); #define XSM_MMU_UPDATE_READ 1 @@ -194,21 +183,6 @@ static inline int xsm_readconsole (uint32_t clear) return xsm_ops->readconsole(clear); } -static inline int xsm_getcpuinfo(void) -{ - return xsm_ops->getcpuinfo(); -} - -static inline int xsm_setpminfo(void) -{ - return xsm_ops->setpminfo(); -} - -static inline int xsm_pm_op(void) -{ - return xsm_ops->pm_op(); -} - static inline int xsm_do_mca(void) { return xsm_ops->do_mca(); @@ -511,56 +485,16 @@ static inline int xsm_apic (struct domain *d, int cmd) return xsm_ops->apic(d, cmd); } -static inline int xsm_xen_settime (void) -{ - return xsm_ops->xen_settime(); -} - static inline int xsm_memtype (uint32_t access) { return xsm_ops->memtype(access); } -static inline int xsm_microcode (void) -{ - return xsm_ops->microcode(); -} - -static inline int xsm_platform_quirk (uint32_t quirk) -{ - return xsm_ops->platform_quirk(quirk); -} - static inline int xsm_platform_op (uint32_t op) { return xsm_ops->platform_op(op); } -static inline int xsm_firmware_info (void) -{ - return xsm_ops->firmware_info(); -} - -static inline int xsm_efi_call (void) -{ - return xsm_ops->efi_call(); -} - -static inline int xsm_acpi_sleep (void) -{ - return xsm_ops->acpi_sleep(); -} - -static inline int xsm_change_freq (void) -{ - return xsm_ops->change_freq(); -} - -static inline int xsm_getidletime (void) -{ - return xsm_ops->getidletime(); -} - static inline int xsm_machine_memory_map(void) { return xsm_ops->machine_memory_map(); diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c index 131a230..e254251 100644 --- a/xen/xsm/dummy.c +++ b/xen/xsm/dummy.c @@ -36,9 +36,6 @@ void xsm_fixup_ops (struct xsm_operations *ops) set_to_dummy_if_null(ops, domctl); set_to_dummy_if_null(ops, sysctl); set_to_dummy_if_null(ops, readconsole); - set_to_dummy_if_null(ops, getcpuinfo); - set_to_dummy_if_null(ops, setpminfo); - set_to_dummy_if_null(ops, pm_op); set_to_dummy_if_null(ops, do_mca); set_to_dummy_if_null(ops, evtchn_unbound); @@ -111,16 +108,7 @@ void xsm_fixup_ops (struct xsm_operations *ops) set_to_dummy_if_null(ops, mem_event_op); set_to_dummy_if_null(ops, mem_sharing_op); set_to_dummy_if_null(ops, apic); - set_to_dummy_if_null(ops, xen_settime); - set_to_dummy_if_null(ops, memtype); - set_to_dummy_if_null(ops, microcode); - set_to_dummy_if_null(ops, platform_quirk); set_to_dummy_if_null(ops, platform_op); - set_to_dummy_if_null(ops, firmware_info); - set_to_dummy_if_null(ops, efi_call); - set_to_dummy_if_null(ops, acpi_sleep); - set_to_dummy_if_null(ops, change_freq); - set_to_dummy_if_null(ops, getidletime); set_to_dummy_if_null(ops, machine_memory_map); set_to_dummy_if_null(ops, domain_memory_map); set_to_dummy_if_null(ops, mmu_update); diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index a8bfddd..f7309fd 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -1177,64 +1177,51 @@ static int flask_apic(struct domain *d, int cmd) return domain_has_xen(d, perm); } -static int flask_xen_settime(void) -{ - return domain_has_xen(current->domain, XEN__SETTIME); -} - -static int flask_memtype(uint32_t access) -{ - u32 perm; - - switch ( access ) - { - case XENPF_add_memtype: - perm = XEN__MTRR_ADD; - break; - case XENPF_del_memtype: - perm = XEN__MTRR_DEL; - break; - case XENPF_read_memtype: - perm = XEN__MTRR_READ; - break; - default: - return -EPERM; - } - - return domain_has_xen(current->domain, perm); -} - -static int flask_microcode(void) -{ - return domain_has_xen(current->domain, XEN__MICROCODE); -} - -static int flask_platform_quirk(uint32_t quirk) -{ - return avc_current_has_perm(SECINITSID_XEN, SECCLASS_XEN, XEN__QUIRK, NULL); -} - static int flask_platform_op(uint32_t op) { switch ( op ) { +#ifdef CONFIG_X86 + /* These operations have their own XSM hooks */ + case XENPF_cpu_online: + case XENPF_cpu_offline: + case XENPF_cpu_hotadd: + case XENPF_mem_hotadd: + return 0; +#endif + case XENPF_settime: + return domain_has_xen(current->domain, XEN__SETTIME); + case XENPF_add_memtype: + return domain_has_xen(current->domain, XEN__MTRR_ADD); + case XENPF_del_memtype: + return domain_has_xen(current->domain, XEN__MTRR_DEL); + case XENPF_read_memtype: + return domain_has_xen(current->domain, XEN__MTRR_READ); + case XENPF_microcode_update: + return domain_has_xen(current->domain, XEN__MICROCODE); + case XENPF_platform_quirk: + return domain_has_xen(current->domain, XEN__QUIRK); + case XENPF_firmware_info: + return domain_has_xen(current->domain, XEN__FIRMWARE); + case XENPF_efi_runtime_call: + return domain_has_xen(current->domain, XEN__FIRMWARE); + case XENPF_enter_acpi_sleep: + return domain_has_xen(current->domain, XEN__SLEEP); + case XENPF_change_freq: + return domain_has_xen(current->domain, XEN__FREQUENCY); + case XENPF_getidletime: - case XENPF_cpu_online: - case XENPF_cpu_offline: - case XENPF_cpu_hotadd: - case XENPF_mem_hotadd: - /* These operations have their own XSM hooks */ - return 0; + return domain_has_xen(current->domain, XEN__GETIDLE); case XENPF_set_processor_pminfo: case XENPF_core_parking: @@ -1250,31 +1237,6 @@ static int flask_platform_op(uint32_t op) } } -static int flask_firmware_info(void) -{ - return domain_has_xen(current->domain, XEN__FIRMWARE); -} - -static int flask_efi_call(void) -{ - return domain_has_xen(current->domain, XEN__FIRMWARE); -} - -static int flask_acpi_sleep(void) -{ - return domain_has_xen(current->domain, XEN__SLEEP); -} - -static int flask_change_freq(void) -{ - return domain_has_xen(current->domain, XEN__FREQUENCY); -} - -static int flask_getidletime(void) -{ - return domain_has_xen(current->domain, XEN__GETIDLE); -} - static int flask_machine_memory_map(void) { return avc_current_has_perm(SECINITSID_XEN, SECCLASS_MMU, MMU__MEMORYMAP, NULL); @@ -1508,16 +1470,7 @@ static struct xsm_operations flask_ops = { .mem_event_op = flask_mem_event_op, .mem_sharing_op = flask_mem_sharing_op, .apic = flask_apic, - .xen_settime = flask_xen_settime, - .memtype = flask_memtype, - .microcode = flask_microcode, - .platform_quirk = flask_platform_quirk, .platform_op = flask_platform_op, - .firmware_info = flask_firmware_info, - .efi_call = flask_efi_call, - .acpi_sleep = flask_acpi_sleep, - .change_freq = flask_change_freq, - .getidletime = flask_getidletime, .machine_memory_map = flask_machine_memory_map, .domain_memory_map = flask_domain_memory_map, .mmu_update = flask_mmu_update, -- 1.7.11.7
Daniel De Graaf
2013-Jan-10 15:33 UTC
[PATCH 18/22] xen/xsm: Add xsm_default parameter to XSM hooks
Include the default XSM hook action as the first argument of the hook to facilitate quick understanding of how the call site is expected to be used (dom0-only, arbitrary guest, or device model). This argument does not solely define how a given hook is interpreted, since any changes to the hook''s default action need to be made identically to all callers of a hook (if there are multiple callers; most hooks only have one), and may also require changing the arguments of the hook. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Acked-by: Tim Deegan <tim@xen.org> Cc: Jan Beulich <jbeulich@suse.com> Cc: Keir Fraser <keir@xen.org> --- xen/arch/x86/cpu/mcheck/mce.c | 2 +- xen/arch/x86/domctl.c | 10 +- xen/arch/x86/hvm/hvm.c | 26 +- xen/arch/x86/irq.c | 2 +- xen/arch/x86/mm.c | 20 +- xen/arch/x86/mm/mem_event.c | 4 +- xen/arch/x86/mm/mem_sharing.c | 4 +- xen/arch/x86/mm/paging.c | 2 +- xen/arch/x86/msi.c | 2 +- xen/arch/x86/physdev.c | 12 +- xen/arch/x86/platform_hypercall.c | 10 +- xen/arch/x86/sysctl.c | 4 +- xen/arch/x86/traps.c | 2 +- xen/common/domain.c | 2 +- xen/common/domctl.c | 10 +- xen/common/event_channel.c | 12 +- xen/common/grant_table.c | 16 +- xen/common/kexec.c | 2 +- xen/common/memory.c | 8 +- xen/common/schedule.c | 2 +- xen/common/sysctl.c | 8 +- xen/common/xenoprof.c | 2 +- xen/drivers/char/console.c | 2 +- xen/drivers/passthrough/iommu.c | 10 +- xen/drivers/passthrough/pci.c | 4 +- xen/include/xsm/dummy.h | 495 +++++++++++++++++++++----------------- xen/include/xsm/xsm.h | 151 ++++++------ 27 files changed, 445 insertions(+), 379 deletions(-) diff --git a/xen/arch/x86/cpu/mcheck/mce.c b/xen/arch/x86/cpu/mcheck/mce.c index 658774a..26273f9 100644 --- a/xen/arch/x86/cpu/mcheck/mce.c +++ b/xen/arch/x86/cpu/mcheck/mce.c @@ -1293,7 +1293,7 @@ long do_mca(XEN_GUEST_HANDLE_PARAM(xen_mc_t) u_xen_mc) struct xen_mc_msrinject *mc_msrinject; struct xen_mc_mceinject *mc_mceinject; - ret = xsm_do_mca(); + ret = xsm_do_mca(XSM_PRIV); if ( ret ) return x86_mcerr(NULL, ret); diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c index 6ab2006..738c87a 100644 --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -77,7 +77,7 @@ long arch_do_domctl( if ( np == 0 ) ret = 0; - else if ( xsm_ioport_permission(d, fp, fp + np - 1, allow) ) + else if ( xsm_ioport_permission(XSM_HOOK, d, fp, fp + np - 1, allow) ) ret = -EPERM; else if ( allow ) ret = ioports_permit_access(d, fp, fp + np - 1); @@ -571,7 +571,7 @@ long arch_do_domctl( if ( !is_hvm_domain(d) ) break; - ret = xsm_bind_pt_irq(d, bind); + ret = xsm_bind_pt_irq(XSM_HOOK, d, bind); if ( ret ) break; @@ -604,7 +604,7 @@ long arch_do_domctl( !irq_access_permitted(current->domain, bind->machine_irq) ) break; - ret = xsm_unbind_pt_irq(d, bind); + ret = xsm_unbind_pt_irq(XSM_HOOK, d, bind); if ( ret ) break; @@ -639,7 +639,7 @@ long arch_do_domctl( !iomem_access_permitted(current->domain, mfn, mfn + nr_mfns - 1) ) break; - ret = xsm_iomem_mapping(d, mfn, mfn + nr_mfns - 1, add); + ret = xsm_iomem_mapping(XSM_HOOK, d, mfn, mfn + nr_mfns - 1, add); if ( ret ) break; @@ -717,7 +717,7 @@ long arch_do_domctl( !ioports_access_permitted(current->domain, fmp, fmp + np - 1) ) break; - ret = xsm_ioport_mapping(d, fmp, fmp + np - 1, add); + ret = xsm_ioport_mapping(XSM_HOOK, d, fmp, fmp + np - 1, add); if ( ret ) break; diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index fa61d7c..24c8b9c 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -3394,7 +3394,7 @@ static int hvmop_set_pci_intx_level( if ( !is_hvm_domain(d) ) goto out; - rc = xsm_hvm_set_pci_intx_level(d); + rc = xsm_hvm_set_pci_intx_level(XSM_DM_PRIV, d); if ( rc ) goto out; @@ -3561,7 +3561,7 @@ static int hvmop_set_isa_irq_level( if ( !is_hvm_domain(d) ) goto out; - rc = xsm_hvm_set_isa_irq_level(d); + rc = xsm_hvm_set_isa_irq_level(XSM_DM_PRIV, d); if ( rc ) goto out; @@ -3605,7 +3605,7 @@ static int hvmop_set_pci_link_route( if ( !is_hvm_domain(d) ) goto out; - rc = xsm_hvm_set_pci_link_route(d); + rc = xsm_hvm_set_pci_link_route(XSM_DM_PRIV, d); if ( rc ) goto out; @@ -3635,7 +3635,7 @@ static int hvmop_inject_msi( if ( !is_hvm_domain(d) ) goto out; - rc = xsm_hvm_inject_msi(d); + rc = xsm_hvm_inject_msi(XSM_DM_PRIV, d); if ( rc ) goto out; @@ -3732,7 +3732,7 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) if ( !is_hvm_domain(d) ) goto param_fail; - rc = xsm_hvm_param(d, op); + rc = xsm_hvm_param(XSM_TARGET, d, op); if ( rc ) goto param_fail; @@ -3981,7 +3981,7 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) if ( a.nr > GB(1) >> PAGE_SHIFT ) goto param_fail2; - rc = xsm_hvm_param(d, op); + rc = xsm_hvm_param(XSM_TARGET, d, op); if ( rc ) goto param_fail2; @@ -4019,7 +4019,7 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) if ( !is_hvm_domain(d) ) goto param_fail3; - rc = xsm_hvm_param(d, op); + rc = xsm_hvm_param(XSM_TARGET, d, op); if ( rc ) goto param_fail3; @@ -4080,7 +4080,7 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) if ( d == NULL ) return -ESRCH; - rc = xsm_hvm_param(d, op); + rc = xsm_hvm_param(XSM_TARGET, d, op); if ( rc ) goto param_fail_getmemtype; @@ -4134,7 +4134,7 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) if ( !is_hvm_domain(d) ) goto param_fail4; - rc = xsm_hvm_param(d, op); + rc = xsm_hvm_param(XSM_TARGET, d, op); if ( rc ) goto param_fail4; @@ -4227,7 +4227,7 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) if ( !is_hvm_domain(d) ) goto param_fail5; - rc = xsm_hvm_param(d, op); + rc = xsm_hvm_param(XSM_TARGET, d, op); if ( rc ) goto param_fail5; @@ -4262,7 +4262,7 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) if ( !is_hvm_domain(d) ) goto param_fail6; - rc = xsm_hvm_param(d, op); + rc = xsm_hvm_param(XSM_TARGET, d, op); if ( rc ) goto param_fail6; @@ -4298,7 +4298,7 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) if ( !is_hvm_domain(d) || !paging_mode_shadow(d) ) goto param_fail7; - rc = xsm_hvm_param(d, op); + rc = xsm_hvm_param(XSM_TARGET, d, op); if ( rc ) goto param_fail7; @@ -4352,7 +4352,7 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) if ( !is_hvm_domain(d) ) goto param_fail8; - rc = xsm_hvm_param(d, op); + rc = xsm_hvm_param(XSM_TARGET, d, op); if ( rc ) goto param_fail8; diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index 238600a..095c17d 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -1874,7 +1874,7 @@ int map_domain_pirq( return 0; } - ret = xsm_map_domain_pirq(d, irq, data); + ret = xsm_map_domain_pirq(XSM_HOOK, d, irq, data); if ( ret ) { dprintk(XENLOG_G_ERR, "dom%d: could not permit access to irq %d mapping to pirq %d\n", diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index c148a08..764a553 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -2700,7 +2700,7 @@ long do_mmuext_op( goto out; } - rc = xsm_mmuext_op(d, pg_owner); + rc = xsm_mmuext_op(XSM_TARGET, d, pg_owner); if ( rc ) { rcu_unlock_domain(pg_owner); @@ -2772,7 +2772,7 @@ long do_mmuext_op( break; } - if ( (rc = xsm_memory_pin_page(d, pg_owner, page)) != 0 ) + if ( (rc = xsm_memory_pin_page(XSM_HOOK, d, pg_owner, page)) != 0 ) { put_page_and_type(page); okay = 0; @@ -3230,7 +3230,7 @@ long do_mmu_update( } if ( xsm_needed != xsm_checked ) { - rc = xsm_mmu_update(d, pt_owner, pg_owner, xsm_needed); + rc = xsm_mmu_update(XSM_TARGET, d, pt_owner, pg_owner, xsm_needed); if ( rc ) break; xsm_checked = xsm_needed; @@ -3349,7 +3349,7 @@ long do_mmu_update( xsm_needed |= XSM_MMU_MACHPHYS_UPDATE; if ( xsm_needed != xsm_checked ) { - rc = xsm_mmu_update(d, NULL, pg_owner, xsm_needed); + rc = xsm_mmu_update(XSM_TARGET, d, NULL, pg_owner, xsm_needed); if ( rc ) break; xsm_checked = xsm_needed; @@ -3917,7 +3917,7 @@ static int __do_update_va_mapping( perfc_incr(calls_to_update_va); - rc = xsm_update_va_mapping(d, pg_owner, val); + rc = xsm_update_va_mapping(XSM_TARGET, d, pg_owner, val); if ( rc ) return rc; @@ -4388,7 +4388,7 @@ long arch_memory_op(int op, XEN_GUEST_HANDLE_PARAM(void) arg) if ( d == NULL ) return -ESRCH; - if ( xsm_add_to_physmap(current->domain, d) ) + if ( xsm_add_to_physmap(XSM_TARGET, current->domain, d) ) { rcu_unlock_domain(d); return -EPERM; @@ -4427,7 +4427,7 @@ long arch_memory_op(int op, XEN_GUEST_HANDLE_PARAM(void) arg) if ( d == NULL ) return -ESRCH; - rc = xsm_domain_memory_map(d); + rc = xsm_domain_memory_map(XSM_TARGET, d); if ( rc ) { rcu_unlock_domain(d); @@ -4502,7 +4502,7 @@ long arch_memory_op(int op, XEN_GUEST_HANDLE_PARAM(void) arg) XEN_GUEST_HANDLE_PARAM(e820entry_t) buffer_param; unsigned int i; - rc = xsm_machine_memory_map(); + rc = xsm_machine_memory_map(XSM_PRIV); if ( rc ) return rc; @@ -4586,9 +4586,9 @@ long arch_memory_op(int op, XEN_GUEST_HANDLE_PARAM(void) arg) return -ESRCH; if ( op == XENMEM_set_pod_target ) - rc = xsm_set_pod_target(d); + rc = xsm_set_pod_target(XSM_PRIV, d); else - rc = xsm_get_pod_target(d); + rc = xsm_get_pod_target(XSM_PRIV, d); if ( rc != 0 ) goto pod_target_out_unlock; diff --git a/xen/arch/x86/mm/mem_event.c b/xen/arch/x86/mm/mem_event.c index c2b3670..4222248 100644 --- a/xen/arch/x86/mm/mem_event.c +++ b/xen/arch/x86/mm/mem_event.c @@ -449,7 +449,7 @@ int do_mem_event_op(int op, uint32_t domain, void *arg) if ( ret ) return ret; - ret = xsm_mem_event_op(d, op); + ret = xsm_mem_event_op(XSM_TARGET, d, op); if ( ret ) goto out; @@ -502,7 +502,7 @@ int mem_event_domctl(struct domain *d, xen_domctl_mem_event_op_t *mec, { int rc; - rc = xsm_mem_event_control(d, mec->mode, mec->op); + rc = xsm_mem_event_control(XSM_PRIV, d, mec->mode, mec->op); if ( rc ) return rc; diff --git a/xen/arch/x86/mm/mem_sharing.c b/xen/arch/x86/mm/mem_sharing.c index 4624314..1caa900 100644 --- a/xen/arch/x86/mm/mem_sharing.c +++ b/xen/arch/x86/mm/mem_sharing.c @@ -1351,7 +1351,7 @@ int mem_sharing_memop(struct domain *d, xen_mem_sharing_op_t *mec) if ( rc ) return rc; - rc = xsm_mem_sharing_op(d, cd, mec->op); + rc = xsm_mem_sharing_op(XSM_TARGET, d, cd, mec->op); if ( rc ) { rcu_unlock_domain(cd); @@ -1415,7 +1415,7 @@ int mem_sharing_memop(struct domain *d, xen_mem_sharing_op_t *mec) if ( rc ) return rc; - rc = xsm_mem_sharing_op(d, cd, mec->op); + rc = xsm_mem_sharing_op(XSM_TARGET, d, cd, mec->op); if ( rc ) { rcu_unlock_domain(cd); diff --git a/xen/arch/x86/mm/paging.c b/xen/arch/x86/mm/paging.c index a5cdbd1..ac9bb1a 100644 --- a/xen/arch/x86/mm/paging.c +++ b/xen/arch/x86/mm/paging.c @@ -559,7 +559,7 @@ int paging_domctl(struct domain *d, xen_domctl_shadow_op_t *sc, return -EINVAL; } - rc = xsm_shadow_control(d, sc->op); + rc = xsm_shadow_control(XSM_HOOK, d, sc->op); if ( rc ) return rc; diff --git a/xen/arch/x86/msi.c b/xen/arch/x86/msi.c index e40ed4f..0e6e50b 100644 --- a/xen/arch/x86/msi.c +++ b/xen/arch/x86/msi.c @@ -1016,7 +1016,7 @@ int pci_restore_msi_state(struct pci_dev *pdev) if (!pdev) return -EINVAL; - ret = xsm_resource_setup_pci((pdev->seg << 16) | (pdev->bus << 8) | pdev->devfn); + ret = xsm_resource_setup_pci(XSM_PRIV, (pdev->seg << 16) | (pdev->bus << 8) | pdev->devfn); if ( ret ) return ret; diff --git a/xen/arch/x86/physdev.c b/xen/arch/x86/physdev.c index 32a861a..b45e18a 100644 --- a/xen/arch/x86/physdev.c +++ b/xen/arch/x86/physdev.c @@ -232,7 +232,7 @@ int physdev_unmap_pirq(domid_t domid, int pirq) goto free_domain; } - ret = xsm_unmap_domain_pirq(d, domain_pirq_to_irq(d, pirq)); + ret = xsm_unmap_domain_pirq(XSM_TARGET, d, domain_pirq_to_irq(d, pirq)); if ( ret ) goto free_domain; @@ -423,7 +423,7 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) ret = -EFAULT; if ( copy_from_guest(&apic, arg, 1) != 0 ) break; - ret = xsm_apic(v->domain, cmd); + ret = xsm_apic(XSM_PRIV, v->domain, cmd); if ( ret ) break; ret = ioapic_guest_read(apic.apic_physbase, apic.reg, &apic.value); @@ -437,7 +437,7 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) ret = -EFAULT; if ( copy_from_guest(&apic, arg, 1) != 0 ) break; - ret = xsm_apic(v->domain, cmd); + ret = xsm_apic(XSM_PRIV, v->domain, cmd); if ( ret ) break; ret = ioapic_guest_write(apic.apic_physbase, apic.reg, apic.value); @@ -453,7 +453,7 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) /* Use the APIC check since this dummy hypercall should still only * be called by the domain with access to program the ioapic */ - ret = xsm_apic(v->domain, cmd); + ret = xsm_apic(XSM_PRIV, v->domain, cmd); if ( ret ) break; @@ -578,7 +578,7 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) case PHYSDEVOP_pci_mmcfg_reserved: { struct physdev_pci_mmcfg_reserved info; - ret = xsm_resource_setup_misc(); + ret = xsm_resource_setup_misc(XSM_PRIV); if ( ret ) break; @@ -632,7 +632,7 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) if ( setup_gsi.gsi < 0 || setup_gsi.gsi >= nr_irqs_gsi ) break; - ret = xsm_resource_setup_gsi(setup_gsi.gsi); + ret = xsm_resource_setup_gsi(XSM_PRIV, setup_gsi.gsi); if ( ret ) break; diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c index a67aff4..5ca2840 100644 --- a/xen/arch/x86/platform_hypercall.c +++ b/xen/arch/x86/platform_hypercall.c @@ -72,7 +72,7 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) if ( op->interface_version != XENPF_INTERFACE_VERSION ) return -EACCES; - ret = xsm_platform_op(op->cmd); + ret = xsm_platform_op(XSM_PRIV, op->cmd); if ( ret ) return ret; @@ -498,7 +498,7 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) { int cpu = op->u.cpu_ol.cpuid; - ret = xsm_resource_plug_core(); + ret = xsm_resource_plug_core(XSM_HOOK); if ( ret ) break; @@ -523,7 +523,7 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) { int cpu = op->u.cpu_ol.cpuid; - ret = xsm_resource_unplug_core(); + ret = xsm_resource_unplug_core(XSM_HOOK); if ( ret ) break; @@ -552,7 +552,7 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) break; case XENPF_cpu_hotadd: - ret = xsm_resource_plug_core(); + ret = xsm_resource_plug_core(XSM_HOOK); if ( ret ) break; @@ -562,7 +562,7 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) break; case XENPF_mem_hotadd: - ret = xsm_resource_plug_core(); + ret = xsm_resource_plug_core(XSM_HOOK); if ( ret ) break; diff --git a/xen/arch/x86/sysctl.c b/xen/arch/x86/sysctl.c index 59e8100..d0be4be 100644 --- a/xen/arch/x86/sysctl.c +++ b/xen/arch/x86/sysctl.c @@ -186,14 +186,14 @@ long arch_do_sysctl( switch ( sysctl->u.cpu_hotplug.op ) { case XEN_SYSCTL_CPU_HOTPLUG_ONLINE: - ret = xsm_resource_plug_core(); + ret = xsm_resource_plug_core(XSM_HOOK); if ( ret ) break; ret = continue_hypercall_on_cpu( 0, cpu_up_helper, (void *)(unsigned long)cpu); break; case XEN_SYSCTL_CPU_HOTPLUG_OFFLINE: - ret = xsm_resource_unplug_core(); + ret = xsm_resource_unplug_core(XSM_HOOK); if ( ret ) break; ret = continue_hypercall_on_cpu( diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 44a866e..7c180ea 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -1643,7 +1643,7 @@ static int pci_cfg_ok(struct domain *d, int write, int size) start |= (d->arch.pci_cf8 >> 16) & 0xF00; } end = start + size - 1; - if (xsm_pci_config_permission(d, machine_bdf, start, end, write)) + if (xsm_pci_config_permission(XSM_HOOK, d, machine_bdf, start, end, write)) return 0; return 1; } diff --git a/xen/common/domain.c b/xen/common/domain.c index ec8efe8..07f62b3 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -252,7 +252,7 @@ struct domain *domain_create( if ( !is_idle_domain(d) ) { - if ( (err = xsm_domain_create(d, ssidref)) != 0 ) + if ( (err = xsm_domain_create(XSM_HOOK, d, ssidref)) != 0 ) goto fail; d->is_paused_by_controller = 1; diff --git a/xen/common/domctl.c b/xen/common/domctl.c index e1fb75d..caa68f7 100644 --- a/xen/common/domctl.c +++ b/xen/common/domctl.c @@ -265,7 +265,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) return -ESRCH; } - ret = xsm_domctl(d, op->cmd); + ret = xsm_domctl(XSM_OTHER, d, op->cmd); if ( ret ) goto domctl_out_unlock_domonly; @@ -579,7 +579,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) break; } - ret = xsm_getdomaininfo(d); + ret = xsm_getdomaininfo(XSM_HOOK, d); if ( ret ) goto getdomaininfo_out; @@ -719,7 +719,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) if ( pirq >= d->nr_pirqs ) ret = -EINVAL; - else if ( xsm_irq_permission(d, pirq, allow) ) + else if ( xsm_irq_permission(XSM_HOOK, d, pirq, allow) ) ret = -EPERM; else if ( allow ) ret = irq_permit_access(d, pirq); @@ -738,7 +738,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) if ( (mfn + nr_mfns - 1) < mfn ) /* wrap? */ break; - if ( xsm_iomem_permission(d, mfn, mfn + nr_mfns - 1, allow) ) + if ( xsm_iomem_permission(XSM_HOOK, d, mfn, mfn + nr_mfns - 1, allow) ) ret = -EPERM; else if ( allow ) ret = iomem_permit_access(d, mfn, mfn + nr_mfns - 1); @@ -770,7 +770,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) break; } - ret = xsm_set_target(d, e); + ret = xsm_set_target(XSM_HOOK, d, e); if ( ret ) { put_domain(e); break; diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c index f620966..2d7afc9 100644 --- a/xen/common/event_channel.c +++ b/xen/common/event_channel.c @@ -175,7 +175,7 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc) ERROR_EXIT_DOM(port, d); chn = evtchn_from_port(d, port); - rc = xsm_evtchn_unbound(d, chn, alloc->remote_dom); + rc = xsm_evtchn_unbound(XSM_TARGET, d, chn, alloc->remote_dom); if ( rc ) goto out; @@ -231,7 +231,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind) (rchn->u.unbound.remote_domid != ld->domain_id) ) ERROR_EXIT_DOM(-EINVAL, rd); - rc = xsm_evtchn_interdomain(ld, lchn, rd, rchn); + rc = xsm_evtchn_interdomain(XSM_HOOK, ld, lchn, rd, rchn); if ( rc ) goto out; @@ -580,7 +580,7 @@ int evtchn_send(struct domain *d, unsigned int lport) return -EINVAL; } - ret = xsm_evtchn_send(ld, lchn); + ret = xsm_evtchn_send(XSM_HOOK, ld, lchn); if ( ret ) goto out; @@ -812,7 +812,7 @@ static long evtchn_status(evtchn_status_t *status) chn = evtchn_from_port(d, port); - rc = xsm_evtchn_status(d, chn); + rc = xsm_evtchn_status(XSM_TARGET, d, chn); if ( rc ) goto out; @@ -954,7 +954,7 @@ static long evtchn_reset(evtchn_reset_t *r) if ( d == NULL ) return -ESRCH; - rc = xsm_evtchn_reset(current->domain, d); + rc = xsm_evtchn_reset(XSM_TARGET, current->domain, d); if ( rc ) goto out; @@ -1101,7 +1101,7 @@ int alloc_unbound_xen_event_channel( goto out; chn = evtchn_from_port(d, port); - rc = xsm_evtchn_unbound(d, chn, remote_domid); + rc = xsm_evtchn_unbound(XSM_TARGET, d, chn, remote_domid); chn->state = ECS_UNBOUND; chn->xen_consumer = get_xen_consumer(notification_fn); diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index 59708c3..f85adb4 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -552,7 +552,7 @@ __gnttab_map_grant_ref( return; } - rc = xsm_grant_mapref(ld, rd, op->flags); + rc = xsm_grant_mapref(XSM_HOOK, ld, rd, op->flags); if ( rc ) { rcu_unlock_domain(rd); @@ -872,7 +872,7 @@ __gnttab_unmap_common( return; } - rc = xsm_grant_unmapref(ld, rd); + rc = xsm_grant_unmapref(XSM_HOOK, ld, rd); if ( rc ) { rcu_unlock_domain(rd); @@ -1336,7 +1336,7 @@ gnttab_setup_table( goto out2; } - if ( xsm_grant_setup(current->domain, d) ) + if ( xsm_grant_setup(XSM_TARGET, current->domain, d) ) { op.status = GNTST_permission_denied; goto out2; @@ -1406,7 +1406,7 @@ gnttab_query_size( goto query_out; } - rc = xsm_grant_query_size(current->domain, d); + rc = xsm_grant_query_size(XSM_TARGET, current->domain, d); if ( rc ) { op.status = GNTST_permission_denied; @@ -1582,7 +1582,7 @@ gnttab_transfer( goto copyback; } - if ( xsm_grant_transfer(d, e) ) + if ( xsm_grant_transfer(XSM_HOOK, d, e) ) { put_gfn(d, gop.mfn); gop.status = GNTST_permission_denied; @@ -2022,7 +2022,7 @@ __gnttab_copy( PIN_FAIL(error_out, GNTST_bad_domain, "couldn''t find %d\n", op->dest.domid); - rc = xsm_grant_copy(sd, dd); + rc = xsm_grant_copy(XSM_HOOK, sd, dd); if ( rc ) { rc = GNTST_permission_denied; @@ -2280,7 +2280,7 @@ gnttab_get_status_frames(XEN_GUEST_HANDLE_PARAM(gnttab_get_status_frames_t) uop, op.status = GNTST_bad_domain; goto out1; } - rc = xsm_grant_setup(current->domain, d); + rc = xsm_grant_setup(XSM_TARGET, current->domain, d); if ( rc ) { op.status = GNTST_permission_denied; goto out1; @@ -2331,7 +2331,7 @@ gnttab_get_version(XEN_GUEST_HANDLE_PARAM(gnttab_get_version_t) uop) if ( d == NULL ) return -ESRCH; - rc = xsm_grant_query_size(current->domain, d); + rc = xsm_grant_query_size(XSM_TARGET, current->domain, d); if ( rc ) { rcu_unlock_domain(d); diff --git a/xen/common/kexec.c b/xen/common/kexec.c index d4f6332..6dd20c6 100644 --- a/xen/common/kexec.c +++ b/xen/common/kexec.c @@ -852,7 +852,7 @@ static int do_kexec_op_internal(unsigned long op, unsigned long flags; int ret = -EINVAL; - ret = xsm_kexec(); + ret = xsm_kexec(XSM_PRIV); if ( ret ) return ret; diff --git a/xen/common/memory.c b/xen/common/memory.c index e18e224..fe79ca0 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -348,7 +348,7 @@ static long memory_exchange(XEN_GUEST_HANDLE_PARAM(xen_memory_exchange_t) arg) goto fail_early; } - rc = xsm_memory_exchange(d); + rc = xsm_memory_exchange(XSM_TARGET, d); if ( rc ) { rcu_unlock_domain(d); @@ -600,7 +600,7 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg) return start_extent; args.domain = d; - rc = xsm_memory_adjust_reservation(current->domain, d); + rc = xsm_memory_adjust_reservation(XSM_TARGET, current->domain, d); if ( rc ) { rcu_unlock_domain(d); @@ -649,7 +649,7 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg) if ( d == NULL ) return -ESRCH; - rc = xsm_memory_stat_reservation(current->domain, d); + rc = xsm_memory_stat_reservation(XSM_TARGET, current->domain, d); if ( rc ) { rcu_unlock_domain(d); @@ -687,7 +687,7 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg) if ( d == NULL ) return -ESRCH; - if ( xsm_remove_from_physmap(current->domain, d) ) + if ( xsm_remove_from_physmap(XSM_TARGET, current->domain, d) ) { rcu_unlock_domain(d); return -EPERM; diff --git a/xen/common/schedule.c b/xen/common/schedule.c index d405081..903f32d 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -921,7 +921,7 @@ ret_t do_sched_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) if ( d == NULL ) break; - ret = xsm_schedop_shutdown(current->domain, d); + ret = xsm_schedop_shutdown(XSM_DM_PRIV, current->domain, d); if ( ret ) { rcu_unlock_domain(d); diff --git a/xen/common/sysctl.c b/xen/common/sysctl.c index 2ebf5e6..d663ed7 100644 --- a/xen/common/sysctl.c +++ b/xen/common/sysctl.c @@ -40,7 +40,7 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl) if ( op->interface_version != XEN_SYSCTL_INTERFACE_VERSION ) return -EACCES; - ret = xsm_sysctl(op->cmd); + ret = xsm_sysctl(XSM_PRIV, op->cmd); if ( ret ) return ret; @@ -57,7 +57,7 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl) switch ( op->cmd ) { case XEN_SYSCTL_readconsole: - ret = xsm_readconsole(op->u.readconsole.clear); + ret = xsm_readconsole(XSM_HOOK, op->u.readconsole.clear); if ( ret ) break; @@ -87,7 +87,7 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl) if ( num_domains == op->u.getdomaininfolist.max_domains ) break; - ret = xsm_getdomaininfo(d); + ret = xsm_getdomaininfo(XSM_HOOK, d); if ( ret ) continue; @@ -186,7 +186,7 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl) uint32_t *status, *ptr; unsigned long pfn; - ret = xsm_page_offline(op->u.page_offline.cmd); + ret = xsm_page_offline(XSM_HOOK, op->u.page_offline.cmd); if ( ret ) break; diff --git a/xen/common/xenoprof.c b/xen/common/xenoprof.c index f545e26..220f1c7 100644 --- a/xen/common/xenoprof.c +++ b/xen/common/xenoprof.c @@ -677,7 +677,7 @@ ret_t do_xenoprof_op(int op, XEN_GUEST_HANDLE_PARAM(void) arg) return -EPERM; } - ret = xsm_profile(current->domain, op); + ret = xsm_profile(XSM_HOOK, current->domain, op); if ( ret ) return ret; diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c index b2c3ee3..e9f696d 100644 --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -406,7 +406,7 @@ long do_console_io(int cmd, int count, XEN_GUEST_HANDLE_PARAM(char) buffer) long rc; unsigned int idx, len; - rc = xsm_console_io(current->domain, cmd); + rc = xsm_console_io(XSM_OTHER, current->domain, cmd); if ( rc ) return rc; diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c index 1cd0007..9a8be10 100644 --- a/xen/drivers/passthrough/iommu.c +++ b/xen/drivers/passthrough/iommu.c @@ -456,7 +456,7 @@ static int iommu_get_device_group( ((pdev->bus == bus) && (pdev->devfn == devfn)) ) continue; - if ( xsm_get_device_group((seg << 16) | (pdev->bus << 8) | pdev->devfn) ) + if ( xsm_get_device_group(XSM_HOOK, (seg << 16) | (pdev->bus << 8) | pdev->devfn) ) continue; sdev_id = ops->get_device_group_id(seg, pdev->bus, pdev->devfn); @@ -559,7 +559,7 @@ int iommu_do_domctl( u32 max_sdevs; XEN_GUEST_HANDLE_64(uint32) sdevs; - ret = xsm_get_device_group(domctl->u.get_device_group.machine_sbdf); + ret = xsm_get_device_group(XSM_HOOK, domctl->u.get_device_group.machine_sbdf); if ( ret ) break; @@ -587,7 +587,7 @@ int iommu_do_domctl( break; case XEN_DOMCTL_test_assign_device: - ret = xsm_test_assign_device(domctl->u.assign_device.machine_sbdf); + ret = xsm_test_assign_device(XSM_HOOK, domctl->u.assign_device.machine_sbdf); if ( ret ) break; @@ -611,7 +611,7 @@ int iommu_do_domctl( break; } - ret = xsm_assign_device(d, domctl->u.assign_device.machine_sbdf); + ret = xsm_assign_device(XSM_HOOK, d, domctl->u.assign_device.machine_sbdf); if ( ret ) break; @@ -630,7 +630,7 @@ int iommu_do_domctl( break; case XEN_DOMCTL_deassign_device: - ret = xsm_deassign_device(d, domctl->u.assign_device.machine_sbdf); + ret = xsm_deassign_device(XSM_HOOK, d, domctl->u.assign_device.machine_sbdf); if ( ret ) break; diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c index a61a9ba..d75b7b7 100644 --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -380,7 +380,7 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn, const struct pci_dev_info *info) pdev_type = "device"; } - ret = xsm_resource_plug_pci((seg << 16) | (bus << 8) | devfn); + ret = xsm_resource_plug_pci(XSM_PRIV, (seg << 16) | (bus << 8) | devfn); if ( ret ) return ret; @@ -496,7 +496,7 @@ int pci_remove_device(u16 seg, u8 bus, u8 devfn) struct pci_dev *pdev; int ret; - ret = xsm_resource_unplug_pci((seg << 16) | (bus << 8) | devfn); + ret = xsm_resource_unplug_pci(XSM_PRIV, (seg << 16) | (bus << 8) | devfn); if ( ret ) return ret; diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index 721fcb4..4f75674 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -6,68 +6,132 @@ * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * as published by the Free Software Foundation. + * + * + * Each XSM hook implementing an access check should have its first parameter + * preceded by XSM_DEFAULT_ARG (or use XSM_DEFAULT_VOID if it has no + * arguments). The first non-declaration statement shold be XSM_ASSERT_ACTION + * with the expected type of the hook, which will either define or check the + * value of action. */ #include <xen/sched.h> #include <xsm/xsm.h> +/* Cannot use BUILD_BUG_ON here because the expressions we check are not + * considered constant at compile time. Instead, rely on constant propagation to + * inline out the calls to this invalid function, which will cause linker errors + * if references remain at link time. + */ +#define LINKER_BUG_ON(x) do { if (x) __xsm_action_mismatch_detected(); } while (0) +/* DO NOT implement this function; it is supposed to trigger link errors */ +void __xsm_action_mismatch_detected(void); + +#ifdef XSM_ENABLE + +/* In XSM_ENABLE builds, this header file is included from xsm/dummy.c, and + * contains static (not inline) functions compiled to the dummy XSM module. + * There is no xsm_default_t argument available, so the value from the assertion + * is used to initialize the variable. + */ +#define XSM_INLINE /* */ +#define XSM_DEFAULT_ARG /* */ +#define XSM_DEFAULT_VOID void +#define XSM_ASSERT_ACTION(def) xsm_default_t action = def; (void)action + +#else /* XSM_ENABLE */ + +/* In !XSM_ENABLE builds, this header file is included from xsm/xsm.h, and + * contains inline functions for each XSM hook. These functions also perform + * compile-time checks on the xsm_default_t argument to ensure that the behavior + * of the dummy XSM module is the same as the behavior with XSM disabled. + */ +#define XSM_INLINE inline +#define XSM_DEFAULT_ARG xsm_default_t action, +#define XSM_DEFAULT_VOID xsm_default_t action +#define XSM_ASSERT_ACTION(def) LINKER_BUG_ON(def != action) + +#endif /* XSM_ENABLE */ + +static inline int xsm_default_action(xsm_default_t action, struct domain *src, + struct domain *target) +{ + switch ( action ) { + case XSM_HOOK: + return 0; + case XSM_DM_PRIV: + if ( !IS_PRIV_FOR(src, target) ) + return -EPERM; + return 0; + case XSM_TARGET: + if ( src != target && !IS_PRIV_FOR(src, target) ) + return -EPERM; + return 0; + case XSM_PRIV: + if ( !IS_PRIV(src) ) + return -EPERM; + return 0; + default: + LINKER_BUG_ON(1); + return -EPERM; + } +} + static XSM_INLINE void xsm_security_domaininfo(struct domain *d, struct xen_domctl_getdomaininfo *info) { return; } -static XSM_INLINE int xsm_domain_create(struct domain *d, u32 ssidref) +static XSM_INLINE int xsm_domain_create(XSM_DEFAULT_ARG struct domain *d, u32 ssidref) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_getdomaininfo(struct domain *d) +static XSM_INLINE int xsm_getdomaininfo(XSM_DEFAULT_ARG struct domain *d) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_set_target(struct domain *d, struct domain *e) +static XSM_INLINE int xsm_set_target(XSM_DEFAULT_ARG struct domain *d, struct domain *e) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_domctl(struct domain *d, int cmd) +static XSM_INLINE int xsm_domctl(XSM_DEFAULT_ARG struct domain *d, int cmd) { + XSM_ASSERT_ACTION(XSM_OTHER); switch ( cmd ) { case XEN_DOMCTL_ioport_mapping: case XEN_DOMCTL_memory_mapping: case XEN_DOMCTL_bind_pt_irq: - case XEN_DOMCTL_unbind_pt_irq: { - if ( !IS_PRIV_FOR(current->domain, d) ) - return -EPERM; - break; - } + case XEN_DOMCTL_unbind_pt_irq: + return xsm_default_action(XSM_DM_PRIV, current->domain, d); default: - if ( !IS_PRIV(current->domain) ) - return -EPERM; + return xsm_default_action(XSM_PRIV, current->domain, d); } - return 0; } -static XSM_INLINE int xsm_sysctl(int cmd) +static XSM_INLINE int xsm_sysctl(XSM_DEFAULT_ARG int cmd) { - if ( !IS_PRIV(current->domain) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_readconsole(uint32_t clear) +static XSM_INLINE int xsm_readconsole(XSM_DEFAULT_ARG uint32_t clear) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_do_mca(void) +static XSM_INLINE int xsm_do_mca(XSM_DEFAULT_VOID) { - if ( !IS_PRIV(current->domain) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, NULL); } static XSM_INLINE int xsm_alloc_security_domain(struct domain *d) @@ -80,109 +144,109 @@ static XSM_INLINE void xsm_free_security_domain(struct domain *d) return; } -static XSM_INLINE int xsm_grant_mapref(struct domain *d1, struct domain *d2, +static XSM_INLINE int xsm_grant_mapref(XSM_DEFAULT_ARG struct domain *d1, struct domain *d2, uint32_t flags) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, d1, d2); } -static XSM_INLINE int xsm_grant_unmapref(struct domain *d1, struct domain *d2) +static XSM_INLINE int xsm_grant_unmapref(XSM_DEFAULT_ARG struct domain *d1, struct domain *d2) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, d1, d2); } -static XSM_INLINE int xsm_grant_setup(struct domain *d1, struct domain *d2) +static XSM_INLINE int xsm_grant_setup(XSM_DEFAULT_ARG struct domain *d1, struct domain *d2) { - if ( d1 != d2 && !IS_PRIV_FOR(d1, d2) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, d1, d2); } -static XSM_INLINE int xsm_grant_transfer(struct domain *d1, struct domain *d2) +static XSM_INLINE int xsm_grant_transfer(XSM_DEFAULT_ARG struct domain *d1, struct domain *d2) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, d1, d2); } -static XSM_INLINE int xsm_grant_copy(struct domain *d1, struct domain *d2) +static XSM_INLINE int xsm_grant_copy(XSM_DEFAULT_ARG struct domain *d1, struct domain *d2) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, d1, d2); } -static XSM_INLINE int xsm_grant_query_size(struct domain *d1, struct domain *d2) +static XSM_INLINE int xsm_grant_query_size(XSM_DEFAULT_ARG struct domain *d1, struct domain *d2) { - if ( d1 != d2 && !IS_PRIV_FOR(d1, d2) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, d1, d2); } -static XSM_INLINE int xsm_memory_exchange(struct domain *d) +static XSM_INLINE int xsm_memory_exchange(XSM_DEFAULT_ARG struct domain *d) { - if ( d != current->domain && !IS_PRIV_FOR(current->domain, d) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_memory_adjust_reservation(struct domain *d1, +static XSM_INLINE int xsm_memory_adjust_reservation(XSM_DEFAULT_ARG struct domain *d1, struct domain *d2) { - if ( d1 != d2 && !IS_PRIV_FOR(d1, d2) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, d1, d2); } -static XSM_INLINE int xsm_memory_stat_reservation(struct domain *d1, struct domain *d2) +static XSM_INLINE int xsm_memory_stat_reservation(XSM_DEFAULT_ARG struct domain *d1, struct domain *d2) { - if ( d1 != d2 && !IS_PRIV_FOR(d1, d2) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, d1, d2); } -static XSM_INLINE int xsm_console_io(struct domain *d, int cmd) +static XSM_INLINE int xsm_console_io(XSM_DEFAULT_ARG struct domain *d, int cmd) { -#ifndef VERBOSE - if ( !IS_PRIV(current->domain) ) - return -EPERM; + XSM_ASSERT_ACTION(XSM_OTHER); +#ifdef VERBOSE + return xsm_default_action(XSM_HOOK, current->domain, NULL); +#else + return xsm_default_action(XSM_PRIV, current->domain, NULL); #endif - return 0; } -static XSM_INLINE int xsm_profile(struct domain *d, int op) +static XSM_INLINE int xsm_profile(XSM_DEFAULT_ARG struct domain *d, int op) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_kexec(void) +static XSM_INLINE int xsm_kexec(XSM_DEFAULT_VOID) { - if ( !IS_PRIV(current->domain) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_schedop_shutdown(struct domain *d1, struct domain *d2) +static XSM_INLINE int xsm_schedop_shutdown(XSM_DEFAULT_ARG struct domain *d1, struct domain *d2) { - if ( !IS_PRIV_FOR(d1, d2) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_DM_PRIV); + return xsm_default_action(action, d1, d2); } -static XSM_INLINE int xsm_memory_pin_page(struct domain *d1, struct domain *d2, +static XSM_INLINE int xsm_memory_pin_page(XSM_DEFAULT_ARG struct domain *d1, struct domain *d2, struct page_info *page) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, d1, d2); } -static XSM_INLINE int xsm_evtchn_unbound(struct domain *d, struct evtchn *chn, +static XSM_INLINE int xsm_evtchn_unbound(XSM_DEFAULT_ARG struct domain *d, struct evtchn *chn, domid_t id2) { - if ( current->domain != d && !IS_PRIV_FOR(current->domain, d) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_evtchn_interdomain(struct domain *d1, struct evtchn +static XSM_INLINE int xsm_evtchn_interdomain(XSM_DEFAULT_ARG struct domain *d1, struct evtchn *chan1, struct domain *d2, struct evtchn *chan2) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, d1, d2); } static XSM_INLINE void xsm_evtchn_close_post(struct evtchn *chn) @@ -190,23 +254,22 @@ static XSM_INLINE void xsm_evtchn_close_post(struct evtchn *chn) return; } -static XSM_INLINE int xsm_evtchn_send(struct domain *d, struct evtchn *chn) +static XSM_INLINE int xsm_evtchn_send(XSM_DEFAULT_ARG struct domain *d, struct evtchn *chn) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_evtchn_status(struct domain *d, struct evtchn *chn) +static XSM_INLINE int xsm_evtchn_status(XSM_DEFAULT_ARG struct domain *d, struct evtchn *chn) { - if ( current->domain != d && !IS_PRIV_FOR(current->domain, d) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_evtchn_reset(struct domain *d1, struct domain *d2) +static XSM_INLINE int xsm_evtchn_reset(XSM_DEFAULT_ARG struct domain *d1, struct domain *d2) { - if ( d1 != d2 && !IS_PRIV_FOR(d1, d2) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, d1, d2); } static XSM_INLINE int xsm_alloc_security_evtchn(struct evtchn *chn) @@ -224,88 +287,88 @@ static XSM_INLINE char *xsm_show_security_evtchn(struct domain *d, const struct return NULL; } -static XSM_INLINE int xsm_get_pod_target(struct domain *d) +static XSM_INLINE int xsm_get_pod_target(XSM_DEFAULT_ARG struct domain *d) { - if ( !IS_PRIV(current->domain) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_set_pod_target(struct domain *d) +static XSM_INLINE int xsm_set_pod_target(XSM_DEFAULT_ARG struct domain *d) { - if ( !IS_PRIV(current->domain) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_get_device_group(uint32_t machine_bdf) +static XSM_INLINE int xsm_get_device_group(XSM_DEFAULT_ARG uint32_t machine_bdf) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_test_assign_device(uint32_t machine_bdf) +static XSM_INLINE int xsm_test_assign_device(XSM_DEFAULT_ARG uint32_t machine_bdf) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_assign_device(struct domain *d, uint32_t machine_bdf) +static XSM_INLINE int xsm_assign_device(XSM_DEFAULT_ARG struct domain *d, uint32_t machine_bdf) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_deassign_device(struct domain *d, uint32_t machine_bdf) +static XSM_INLINE int xsm_deassign_device(XSM_DEFAULT_ARG struct domain *d, uint32_t machine_bdf) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_resource_plug_core(void) +static XSM_INLINE int xsm_resource_plug_core(XSM_DEFAULT_VOID) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_resource_unplug_core(void) +static XSM_INLINE int xsm_resource_unplug_core(XSM_DEFAULT_VOID) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_resource_plug_pci(uint32_t machine_bdf) +static XSM_INLINE int xsm_resource_plug_pci(XSM_DEFAULT_ARG uint32_t machine_bdf) { - if ( !IS_PRIV(current->domain) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_resource_unplug_pci(uint32_t machine_bdf) +static XSM_INLINE int xsm_resource_unplug_pci(XSM_DEFAULT_ARG uint32_t machine_bdf) { - if ( !IS_PRIV(current->domain) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_resource_setup_pci(uint32_t machine_bdf) +static XSM_INLINE int xsm_resource_setup_pci(XSM_DEFAULT_ARG uint32_t machine_bdf) { - if ( !IS_PRIV(current->domain) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_resource_setup_gsi(int gsi) +static XSM_INLINE int xsm_resource_setup_gsi(XSM_DEFAULT_ARG int gsi) { - if ( !IS_PRIV(current->domain) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_resource_setup_misc(void) +static XSM_INLINE int xsm_resource_setup_misc(XSM_DEFAULT_VOID) { - if ( !IS_PRIV(current->domain) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_page_offline(uint32_t cmd) +static XSM_INLINE int xsm_page_offline(XSM_DEFAULT_ARG uint32_t cmd) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, NULL); } static XSM_INLINE long xsm_do_xsm_op(XEN_GUEST_HANDLE_PARAM(xsm_op_t) op) @@ -318,187 +381,179 @@ static XSM_INLINE char *xsm_show_irq_sid(int irq) return NULL; } -static XSM_INLINE int xsm_map_domain_pirq(struct domain *d, int irq, void *data) +static XSM_INLINE int xsm_map_domain_pirq(XSM_DEFAULT_ARG struct domain *d, int irq, void *data) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_unmap_domain_pirq(struct domain *d, int irq) +static XSM_INLINE int xsm_unmap_domain_pirq(XSM_DEFAULT_ARG struct domain *d, int irq) { - if ( !IS_PRIV_FOR(current->domain, d) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_irq_permission(struct domain *d, int pirq, uint8_t allow) +static XSM_INLINE int xsm_irq_permission(XSM_DEFAULT_ARG struct domain *d, int pirq, uint8_t allow) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_iomem_permission(struct domain *d, uint64_t s, uint64_t e, uint8_t allow) +static XSM_INLINE int xsm_iomem_permission(XSM_DEFAULT_ARG struct domain *d, uint64_t s, uint64_t e, uint8_t allow) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_iomem_mapping(struct domain *d, uint64_t s, uint64_t e, uint8_t allow) +static XSM_INLINE int xsm_iomem_mapping(XSM_DEFAULT_ARG struct domain *d, uint64_t s, uint64_t e, uint8_t allow) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_pci_config_permission(struct domain *d, uint32_t machine_bdf, +static XSM_INLINE int xsm_pci_config_permission(XSM_DEFAULT_ARG struct domain *d, uint32_t machine_bdf, uint16_t start, uint16_t end, uint8_t access) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } #ifdef CONFIG_X86 -static XSM_INLINE int xsm_shadow_control(struct domain *d, uint32_t op) +static XSM_INLINE int xsm_shadow_control(XSM_DEFAULT_ARG struct domain *d, uint32_t op) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_hvm_param(struct domain *d, unsigned long op) +static XSM_INLINE int xsm_hvm_param(XSM_DEFAULT_ARG struct domain *d, unsigned long op) { - if ( current->domain != d && !IS_PRIV_FOR(current->domain, d) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_hvm_set_pci_intx_level(struct domain *d) +static XSM_INLINE int xsm_hvm_set_pci_intx_level(XSM_DEFAULT_ARG struct domain *d) { - if ( !IS_PRIV_FOR(current->domain, d) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_DM_PRIV); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_hvm_set_isa_irq_level(struct domain *d) +static XSM_INLINE int xsm_hvm_set_isa_irq_level(XSM_DEFAULT_ARG struct domain *d) { - if ( !IS_PRIV_FOR(current->domain, d) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_DM_PRIV); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_hvm_set_pci_link_route(struct domain *d) +static XSM_INLINE int xsm_hvm_set_pci_link_route(XSM_DEFAULT_ARG struct domain *d) { - if ( !IS_PRIV_FOR(current->domain, d) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_DM_PRIV); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_hvm_inject_msi(struct domain *d) +static XSM_INLINE int xsm_hvm_inject_msi(XSM_DEFAULT_ARG struct domain *d) { - if ( !IS_PRIV_FOR(current->domain, d) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_DM_PRIV); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_mem_event_control(struct domain *d, int mode, int op) +static XSM_INLINE int xsm_mem_event_control(XSM_DEFAULT_ARG struct domain *d, int mode, int op) { - if ( !IS_PRIV(current->domain) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_mem_event_op(struct domain *d, int op) +static XSM_INLINE int xsm_mem_event_op(XSM_DEFAULT_ARG struct domain *d, int op) { - if ( !IS_PRIV_FOR(current->domain, d) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_mem_sharing_op(struct domain *d, struct domain *cd, int op) +static XSM_INLINE int xsm_mem_sharing_op(XSM_DEFAULT_ARG struct domain *d, struct domain *cd, int op) { - if ( !IS_PRIV_FOR(current->domain, cd) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, current->domain, cd); } -static XSM_INLINE int xsm_apic(struct domain *d, int cmd) +static XSM_INLINE int xsm_apic(XSM_DEFAULT_ARG struct domain *d, int cmd) { - if ( !IS_PRIV(d) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, d, NULL); } -static XSM_INLINE int xsm_platform_op(uint32_t op) +static XSM_INLINE int xsm_platform_op(XSM_DEFAULT_ARG uint32_t op) { - if ( !IS_PRIV(current->domain) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_machine_memory_map(void) +static XSM_INLINE int xsm_machine_memory_map(XSM_DEFAULT_VOID) { - if ( !IS_PRIV(current->domain) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_domain_memory_map(struct domain *d) +static XSM_INLINE int xsm_domain_memory_map(XSM_DEFAULT_ARG struct domain *d) { - if ( current->domain != d && !IS_PRIV_FOR(current->domain, d) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_mmu_update(struct domain *d, struct domain *t, +static XSM_INLINE int xsm_mmu_update(XSM_DEFAULT_ARG struct domain *d, struct domain *t, struct domain *f, uint32_t flags) { + XSM_ASSERT_ACTION(XSM_TARGET); if ( t && d != t && !IS_PRIV_FOR(d, t) ) return -EPERM; - if ( d != f && !IS_PRIV_FOR(d, f) ) - return -EPERM; - return 0; + return xsm_default_action(action, d, f); } -static XSM_INLINE int xsm_mmuext_op(struct domain *d, struct domain *f) +static XSM_INLINE int xsm_mmuext_op(XSM_DEFAULT_ARG struct domain *d, struct domain *f) { - if ( d != f && !IS_PRIV_FOR(d, f) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, d, f); } -static XSM_INLINE int xsm_update_va_mapping(struct domain *d, struct domain *f, +static XSM_INLINE int xsm_update_va_mapping(XSM_DEFAULT_ARG struct domain *d, struct domain *f, l1_pgentry_t pte) { - if ( d != f && !IS_PRIV_FOR(d, f) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, d, f); } -static XSM_INLINE int xsm_add_to_physmap(struct domain *d1, struct domain *d2) +static XSM_INLINE int xsm_add_to_physmap(XSM_DEFAULT_ARG struct domain *d1, struct domain *d2) { - if ( d1 != d2 && !IS_PRIV_FOR(d1, d2) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, d1, d2); } -static XSM_INLINE int xsm_remove_from_physmap(struct domain *d1, struct domain *d2) +static XSM_INLINE int xsm_remove_from_physmap(XSM_DEFAULT_ARG struct domain *d1, struct domain *d2) { - if ( d1 != d2 && !IS_PRIV_FOR(d1, d2) ) - return -EPERM; - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, d1, d2); } -static XSM_INLINE int xsm_bind_pt_irq(struct domain *d, struct xen_domctl_bind_pt_irq *bind) +static XSM_INLINE int xsm_bind_pt_irq(XSM_DEFAULT_ARG struct domain *d, struct xen_domctl_bind_pt_irq *bind) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_unbind_pt_irq(struct domain *d, struct xen_domctl_bind_pt_irq *bind) +static XSM_INLINE int xsm_unbind_pt_irq(XSM_DEFAULT_ARG struct domain *d, struct xen_domctl_bind_pt_irq *bind) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_ioport_permission(struct domain *d, uint32_t s, uint32_t e, uint8_t allow) +static XSM_INLINE int xsm_ioport_permission(XSM_DEFAULT_ARG struct domain *d, uint32_t s, uint32_t e, uint8_t allow) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_ioport_mapping(struct domain *d, uint32_t s, uint32_t e, uint8_t allow) +static XSM_INLINE int xsm_ioport_mapping(XSM_DEFAULT_ARG struct domain *d, uint32_t s, uint32_t e, uint8_t allow) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } #endif diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index 7b62d78..17b0899 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -27,6 +27,18 @@ typedef u32 xsm_magic_t; #define XSM_MAGIC 0x00000000 #endif +/* These annotations are used by callers and in dummy.h to document the + * default actions of XSM hooks. They should be compiled out otherwise. + */ +enum xsm_default { + XSM_HOOK, /* Guests can normally access the hypercall */ + XSM_DM_PRIV, /* Device model can perform on its target domain */ + XSM_TARGET, /* Can perform on self or your target domain */ + XSM_PRIV, /* Privileged - normally restricted to dom0 */ + XSM_OTHER /* Something more complex */ +}; +typedef enum xsm_default xsm_default_t; + extern char *policy_buffer; extern u32 policy_size; @@ -153,48 +165,48 @@ static inline void xsm_security_domaininfo (struct domain *d, xsm_ops->security_domaininfo(d, info); } -static inline int xsm_domain_create (struct domain *d, u32 ssidref) +static inline int xsm_domain_create (xsm_default_t def, struct domain *d, u32 ssidref) { return xsm_ops->domain_create(d, ssidref); } -static inline int xsm_getdomaininfo (struct domain *d) +static inline int xsm_getdomaininfo (xsm_default_t def, struct domain *d) { return xsm_ops->getdomaininfo(d); } -static inline int xsm_set_target (struct domain *d, struct domain *e) +static inline int xsm_set_target (xsm_default_t def, struct domain *d, struct domain *e) { return xsm_ops->set_target(d, e); } -static inline int xsm_domctl (struct domain *d, int cmd) +static inline int xsm_domctl (xsm_default_t def, struct domain *d, int cmd) { return xsm_ops->domctl(d, cmd); } -static inline int xsm_sysctl (int cmd) +static inline int xsm_sysctl (xsm_default_t def, int cmd) { return xsm_ops->sysctl(cmd); } -static inline int xsm_readconsole (uint32_t clear) +static inline int xsm_readconsole (xsm_default_t def, uint32_t clear) { return xsm_ops->readconsole(clear); } -static inline int xsm_do_mca(void) +static inline int xsm_do_mca(xsm_default_t def) { return xsm_ops->do_mca(); } -static inline int xsm_evtchn_unbound (struct domain *d1, struct evtchn *chn, +static inline int xsm_evtchn_unbound (xsm_default_t def, struct domain *d1, struct evtchn *chn, domid_t id2) { return xsm_ops->evtchn_unbound(d1, chn, id2); } -static inline int xsm_evtchn_interdomain (struct domain *d1, +static inline int xsm_evtchn_interdomain (xsm_default_t def, struct domain *d1, struct evtchn *chan1, struct domain *d2, struct evtchn *chan2) { return xsm_ops->evtchn_interdomain(d1, chan1, d2, chan2); @@ -205,48 +217,48 @@ static inline void xsm_evtchn_close_post (struct evtchn *chn) xsm_ops->evtchn_close_post(chn); } -static inline int xsm_evtchn_send (struct domain *d, struct evtchn *chn) +static inline int xsm_evtchn_send (xsm_default_t def, struct domain *d, struct evtchn *chn) { return xsm_ops->evtchn_send(d, chn); } -static inline int xsm_evtchn_status (struct domain *d, struct evtchn *chn) +static inline int xsm_evtchn_status (xsm_default_t def, struct domain *d, struct evtchn *chn) { return xsm_ops->evtchn_status(d, chn); } -static inline int xsm_evtchn_reset (struct domain *d1, struct domain *d2) +static inline int xsm_evtchn_reset (xsm_default_t def, struct domain *d1, struct domain *d2) { return xsm_ops->evtchn_reset(d1, d2); } -static inline int xsm_grant_mapref (struct domain *d1, struct domain *d2, +static inline int xsm_grant_mapref (xsm_default_t def, struct domain *d1, struct domain *d2, uint32_t flags) { return xsm_ops->grant_mapref(d1, d2, flags); } -static inline int xsm_grant_unmapref (struct domain *d1, struct domain *d2) +static inline int xsm_grant_unmapref (xsm_default_t def, struct domain *d1, struct domain *d2) { return xsm_ops->grant_unmapref(d1, d2); } -static inline int xsm_grant_setup (struct domain *d1, struct domain *d2) +static inline int xsm_grant_setup (xsm_default_t def, struct domain *d1, struct domain *d2) { return xsm_ops->grant_setup(d1, d2); } -static inline int xsm_grant_transfer (struct domain *d1, struct domain *d2) +static inline int xsm_grant_transfer (xsm_default_t def, struct domain *d1, struct domain *d2) { return xsm_ops->grant_transfer(d1, d2); } -static inline int xsm_grant_copy (struct domain *d1, struct domain *d2) +static inline int xsm_grant_copy (xsm_default_t def, struct domain *d1, struct domain *d2) { return xsm_ops->grant_copy(d1, d2); } -static inline int xsm_grant_query_size (struct domain *d1, struct domain *d2) +static inline int xsm_grant_query_size (xsm_default_t def, struct domain *d1, struct domain *d2) { return xsm_ops->grant_query_size(d1, d2); } @@ -276,60 +288,60 @@ static inline char *xsm_show_security_evtchn (struct domain *d, const struct evt return xsm_ops->show_security_evtchn(d, chn); } -static inline int xsm_get_pod_target (struct domain *d) +static inline int xsm_get_pod_target (xsm_default_t def, struct domain *d) { return xsm_ops->get_pod_target(d); } -static inline int xsm_set_pod_target (struct domain *d) +static inline int xsm_set_pod_target (xsm_default_t def, struct domain *d) { return xsm_ops->set_pod_target(d); } -static inline int xsm_memory_exchange (struct domain *d) +static inline int xsm_memory_exchange (xsm_default_t def, struct domain *d) { return xsm_ops->memory_exchange(d); } -static inline int xsm_memory_adjust_reservation (struct domain *d1, struct +static inline int xsm_memory_adjust_reservation (xsm_default_t def, struct domain *d1, struct domain *d2) { return xsm_ops->memory_adjust_reservation(d1, d2); } -static inline int xsm_memory_stat_reservation (struct domain *d1, +static inline int xsm_memory_stat_reservation (xsm_default_t def, struct domain *d1, struct domain *d2) { return xsm_ops->memory_stat_reservation(d1, d2); } -static inline int xsm_memory_pin_page(struct domain *d1, struct domain *d2, +static inline int xsm_memory_pin_page(xsm_default_t def, struct domain *d1, struct domain *d2, struct page_info *page) { return xsm_ops->memory_pin_page(d1, d2, page); } -static inline int xsm_remove_from_physmap(struct domain *d1, struct domain *d2) +static inline int xsm_remove_from_physmap(xsm_default_t def, struct domain *d1, struct domain *d2) { return xsm_ops->remove_from_physmap(d1, d2); } -static inline int xsm_console_io (struct domain *d, int cmd) +static inline int xsm_console_io (xsm_default_t def, struct domain *d, int cmd) { return xsm_ops->console_io(d, cmd); } -static inline int xsm_profile (struct domain *d, int op) +static inline int xsm_profile (xsm_default_t def, struct domain *d, int op) { return xsm_ops->profile(d, op); } -static inline int xsm_kexec (void) +static inline int xsm_kexec (xsm_default_t def) { return xsm_ops->kexec(); } -static inline int xsm_schedop_shutdown (struct domain *d1, struct domain *d2) +static inline int xsm_schedop_shutdown (xsm_default_t def, struct domain *d1, struct domain *d2) { return xsm_ops->schedop_shutdown(d1, d2); } @@ -339,92 +351,92 @@ static inline char *xsm_show_irq_sid (int irq) return xsm_ops->show_irq_sid(irq); } -static inline int xsm_map_domain_pirq (struct domain *d, int irq, void *data) +static inline int xsm_map_domain_pirq (xsm_default_t def, struct domain *d, int irq, void *data) { return xsm_ops->map_domain_pirq(d, irq, data); } -static inline int xsm_unmap_domain_pirq (struct domain *d, int irq) +static inline int xsm_unmap_domain_pirq (xsm_default_t def, struct domain *d, int irq) { return xsm_ops->unmap_domain_pirq(d, irq); } -static inline int xsm_irq_permission (struct domain *d, int pirq, uint8_t allow) +static inline int xsm_irq_permission (xsm_default_t def, struct domain *d, int pirq, uint8_t allow) { return xsm_ops->irq_permission(d, pirq, allow); } -static inline int xsm_iomem_permission (struct domain *d, uint64_t s, uint64_t e, uint8_t allow) +static inline int xsm_iomem_permission (xsm_default_t def, struct domain *d, uint64_t s, uint64_t e, uint8_t allow) { return xsm_ops->iomem_permission(d, s, e, allow); } -static inline int xsm_iomem_mapping (struct domain *d, uint64_t s, uint64_t e, uint8_t allow) +static inline int xsm_iomem_mapping (xsm_default_t def, struct domain *d, uint64_t s, uint64_t e, uint8_t allow) { return xsm_ops->iomem_mapping(d, s, e, allow); } -static inline int xsm_pci_config_permission (struct domain *d, uint32_t machine_bdf, uint16_t start, uint16_t end, uint8_t access) +static inline int xsm_pci_config_permission (xsm_default_t def, struct domain *d, uint32_t machine_bdf, uint16_t start, uint16_t end, uint8_t access) { return xsm_ops->pci_config_permission(d, machine_bdf, start, end, access); } -static inline int xsm_get_device_group(uint32_t machine_bdf) +static inline int xsm_get_device_group(xsm_default_t def, uint32_t machine_bdf) { return xsm_ops->get_device_group(machine_bdf); } -static inline int xsm_test_assign_device(uint32_t machine_bdf) +static inline int xsm_test_assign_device(xsm_default_t def, uint32_t machine_bdf) { return xsm_ops->test_assign_device(machine_bdf); } -static inline int xsm_assign_device(struct domain *d, uint32_t machine_bdf) +static inline int xsm_assign_device(xsm_default_t def, struct domain *d, uint32_t machine_bdf) { return xsm_ops->assign_device(d, machine_bdf); } -static inline int xsm_deassign_device(struct domain *d, uint32_t machine_bdf) +static inline int xsm_deassign_device(xsm_default_t def, struct domain *d, uint32_t machine_bdf) { return xsm_ops->deassign_device(d, machine_bdf); } -static inline int xsm_resource_plug_pci (uint32_t machine_bdf) +static inline int xsm_resource_plug_pci (xsm_default_t def, uint32_t machine_bdf) { return xsm_ops->resource_plug_pci(machine_bdf); } -static inline int xsm_resource_unplug_pci (uint32_t machine_bdf) +static inline int xsm_resource_unplug_pci (xsm_default_t def, uint32_t machine_bdf) { return xsm_ops->resource_unplug_pci(machine_bdf); } -static inline int xsm_resource_plug_core (void) +static inline int xsm_resource_plug_core (xsm_default_t def) { return xsm_ops->resource_plug_core(); } -static inline int xsm_resource_unplug_core (void) +static inline int xsm_resource_unplug_core (xsm_default_t def) { return xsm_ops->resource_unplug_core(); } -static inline int xsm_resource_setup_pci (uint32_t machine_bdf) +static inline int xsm_resource_setup_pci (xsm_default_t def, uint32_t machine_bdf) { return xsm_ops->resource_setup_pci(machine_bdf); } -static inline int xsm_resource_setup_gsi (int gsi) +static inline int xsm_resource_setup_gsi (xsm_default_t def, int gsi) { return xsm_ops->resource_setup_gsi(gsi); } -static inline int xsm_resource_setup_misc (void) +static inline int xsm_resource_setup_misc (xsm_default_t def) { return xsm_ops->resource_setup_misc(); } -static inline int xsm_page_offline(uint32_t cmd) +static inline int xsm_page_offline(xsm_default_t def, uint32_t cmd) { return xsm_ops->page_offline(cmd); } @@ -435,116 +447,116 @@ static inline long xsm_do_xsm_op (XEN_GUEST_HANDLE_PARAM(xsm_op_t) op) } #ifdef CONFIG_X86 -static inline int xsm_shadow_control (struct domain *d, uint32_t op) +static inline int xsm_shadow_control (xsm_default_t def, struct domain *d, uint32_t op) { return xsm_ops->shadow_control(d, op); } -static inline int xsm_hvm_param (struct domain *d, unsigned long op) +static inline int xsm_hvm_param (xsm_default_t def, struct domain *d, unsigned long op) { return xsm_ops->hvm_param(d, op); } -static inline int xsm_hvm_set_pci_intx_level (struct domain *d) +static inline int xsm_hvm_set_pci_intx_level (xsm_default_t def, struct domain *d) { return xsm_ops->hvm_set_pci_intx_level(d); } -static inline int xsm_hvm_set_isa_irq_level (struct domain *d) +static inline int xsm_hvm_set_isa_irq_level (xsm_default_t def, struct domain *d) { return xsm_ops->hvm_set_isa_irq_level(d); } -static inline int xsm_hvm_set_pci_link_route (struct domain *d) +static inline int xsm_hvm_set_pci_link_route (xsm_default_t def, struct domain *d) { return xsm_ops->hvm_set_pci_link_route(d); } -static inline int xsm_hvm_inject_msi (struct domain *d) +static inline int xsm_hvm_inject_msi (xsm_default_t def, struct domain *d) { return xsm_ops->hvm_inject_msi(d); } -static inline int xsm_mem_event_control (struct domain *d, int mode, int op) +static inline int xsm_mem_event_control (xsm_default_t def, struct domain *d, int mode, int op) { return xsm_ops->mem_event_control(d, mode, op); } -static inline int xsm_mem_event_op (struct domain *d, int op) +static inline int xsm_mem_event_op (xsm_default_t def, struct domain *d, int op) { return xsm_ops->mem_event_op(d, op); } -static inline int xsm_mem_sharing_op (struct domain *d, struct domain *cd, int op) +static inline int xsm_mem_sharing_op (xsm_default_t def, struct domain *d, struct domain *cd, int op) { return xsm_ops->mem_sharing_op(d, cd, op); } -static inline int xsm_apic (struct domain *d, int cmd) +static inline int xsm_apic (xsm_default_t def, struct domain *d, int cmd) { return xsm_ops->apic(d, cmd); } -static inline int xsm_memtype (uint32_t access) +static inline int xsm_memtype (xsm_default_t def, uint32_t access) { return xsm_ops->memtype(access); } -static inline int xsm_platform_op (uint32_t op) +static inline int xsm_platform_op (xsm_default_t def, uint32_t op) { return xsm_ops->platform_op(op); } -static inline int xsm_machine_memory_map(void) +static inline int xsm_machine_memory_map(xsm_default_t def) { return xsm_ops->machine_memory_map(); } -static inline int xsm_domain_memory_map(struct domain *d) +static inline int xsm_domain_memory_map(xsm_default_t def, struct domain *d) { return xsm_ops->domain_memory_map(d); } -static inline int xsm_mmu_update (struct domain *d, struct domain *t, +static inline int xsm_mmu_update (xsm_default_t def, struct domain *d, struct domain *t, struct domain *f, uint32_t flags) { return xsm_ops->mmu_update(d, t, f, flags); } -static inline int xsm_mmuext_op (struct domain *d, struct domain *f) +static inline int xsm_mmuext_op (xsm_default_t def, struct domain *d, struct domain *f) { return xsm_ops->mmuext_op(d, f); } -static inline int xsm_update_va_mapping(struct domain *d, struct domain *f, +static inline int xsm_update_va_mapping(xsm_default_t def, struct domain *d, struct domain *f, l1_pgentry_t pte) { return xsm_ops->update_va_mapping(d, f, pte); } -static inline int xsm_add_to_physmap(struct domain *d1, struct domain *d2) +static inline int xsm_add_to_physmap(xsm_default_t def, struct domain *d1, struct domain *d2) { return xsm_ops->add_to_physmap(d1, d2); } -static inline int xsm_bind_pt_irq(struct domain *d, +static inline int xsm_bind_pt_irq(xsm_default_t def, struct domain *d, struct xen_domctl_bind_pt_irq *bind) { return xsm_ops->bind_pt_irq(d, bind); } -static inline int xsm_unbind_pt_irq(struct domain *d, +static inline int xsm_unbind_pt_irq(xsm_default_t def, struct domain *d, struct xen_domctl_bind_pt_irq *bind) { return xsm_ops->unbind_pt_irq(d, bind); } -static inline int xsm_ioport_permission (struct domain *d, uint32_t s, uint32_t e, uint8_t allow) +static inline int xsm_ioport_permission (xsm_default_t def, struct domain *d, uint32_t s, uint32_t e, uint8_t allow) { return xsm_ops->ioport_permission(d, s, e, allow); } -static inline int xsm_ioport_mapping (struct domain *d, uint32_t s, uint32_t e, uint8_t allow) +static inline int xsm_ioport_mapping (xsm_default_t def, struct domain *d, uint32_t s, uint32_t e, uint8_t allow) { return xsm_ops->ioport_mapping(d, s, e, allow); } @@ -564,7 +576,6 @@ extern void xsm_fixup_ops(struct xsm_operations *ops); #else /* XSM_ENABLE */ -#define XSM_INLINE inline #include <xsm/dummy.h> static inline int xsm_init (unsigned long *module_map, -- 1.7.11.7
This adds a pair of XSM hooks for tmem operations: xsm_tmem_op which controls any use of tmem, and xsm_tmem_control which allows use of the TMEM_CONTROL operations. By default, all domains can use tmem while only IS_PRIV domains can use control operations. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Acked-by: Dan Magenheimer <dan.magenheimer@oracle.com> --- tools/flask/policy/policy/modules/xen/xen.te | 5 ++++- xen/common/tmem.c | 3 +++ xen/include/xen/tmem_xen.h | 8 +++++++- xen/include/xsm/dummy.h | 12 ++++++++++++ xen/include/xsm/xsm.h | 12 ++++++++++++ xen/xsm/dummy.c | 2 ++ xen/xsm/flask/hooks.c | 12 ++++++++++++ xen/xsm/flask/policy/access_vectors | 2 ++ 8 files changed, 54 insertions(+), 2 deletions(-) diff --git a/tools/flask/policy/policy/modules/xen/xen.te b/tools/flask/policy/policy/modules/xen/xen.te index 8c77e6b..c714dcb 100644 --- a/tools/flask/policy/policy/modules/xen/xen.te +++ b/tools/flask/policy/policy/modules/xen/xen.te @@ -56,7 +56,7 @@ type device_t, resource_type; ################################################################################ allow dom0_t xen_t:xen { kexec readapic writeapic mtrr_read mtrr_add mtrr_del scheduler physinfo heap quirk readconsole writeconsole settime getcpuinfo - microcode cpupool_op sched_op pm_op }; + microcode cpupool_op sched_op pm_op tmem_control }; allow dom0_t xen_t:mmu { memorymap }; allow dom0_t security_t:security { check_context compute_av compute_create compute_member load_policy compute_relabel compute_user setenforce @@ -74,6 +74,9 @@ domain_comms(dom0_t, dom0_t) auditallow dom0_t security_t:security { load_policy setenforce setbool }; +# Allow all domains to use (unprivileged parts of) the tmem hypercall +allow domain_type xen_t:xen tmem_op; + ############################################################################### # # Domain creation diff --git a/xen/common/tmem.c b/xen/common/tmem.c index 44e2772..ca70e86 100644 --- a/xen/common/tmem.c +++ b/xen/common/tmem.c @@ -2644,6 +2644,9 @@ EXPORT long do_tmem_op(tmem_cli_op_t uops) if ( !tmem_initialized ) return -ENODEV; + if ( !tmh_current_permitted() ) + return -EPERM; + total_tmem_ops++; if ( tmh_lock_all ) diff --git a/xen/include/xen/tmem_xen.h b/xen/include/xen/tmem_xen.h index 36a8d9f..ad1ddd5 100644 --- a/xen/include/xen/tmem_xen.h +++ b/xen/include/xen/tmem_xen.h @@ -16,6 +16,7 @@ #include <xen/guest_access.h> /* copy_from_guest */ #include <xen/hash.h> /* hash_long */ #include <xen/domain_page.h> /* __map_domain_page */ +#include <xsm/xsm.h> /* xsm_tmem_control */ #include <public/tmem.h> #ifdef CONFIG_COMPAT #include <compat/tmem.h> @@ -326,9 +327,14 @@ static inline bool_t tmh_set_client_from_id( return rc; } +static inline bool_t tmh_current_permitted(void) +{ + return !xsm_tmem_op(XSM_HOOK); +} + static inline bool_t tmh_current_is_privileged(void) { - return IS_PRIV(current->domain); + return !xsm_tmem_control(XSM_PRIV); } static inline uint8_t tmh_get_first_byte(pfp_t *pfp) diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index 4f75674..2c750de 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -371,6 +371,18 @@ static XSM_INLINE int xsm_page_offline(XSM_DEFAULT_ARG uint32_t cmd) return xsm_default_action(action, current->domain, NULL); } +static XSM_INLINE int xsm_tmem_op(XSM_DEFAULT_VOID) +{ + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, NULL); +} + +static XSM_INLINE int xsm_tmem_control(XSM_DEFAULT_VOID) +{ + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, NULL); +} + static XSM_INLINE long xsm_do_xsm_op(XEN_GUEST_HANDLE_PARAM(xsm_op_t) op) { return -ENOSYS; diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index 17b0899..ce5ede8 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -119,6 +119,8 @@ struct xsm_operations { int (*resource_setup_misc) (void); int (*page_offline)(uint32_t cmd); + int (*tmem_op)(void); + int (*tmem_control)(void); long (*do_xsm_op) (XEN_GUEST_HANDLE_PARAM(xsm_op_t) op); @@ -441,6 +443,16 @@ static inline int xsm_page_offline(xsm_default_t def, uint32_t cmd) return xsm_ops->page_offline(cmd); } +static inline int xsm_tmem_op(xsm_default_t def) +{ + return xsm_ops->tmem_op(); +} + +static inline int xsm_tmem_control(xsm_default_t def) +{ + return xsm_ops->tmem_control(); +} + static inline long xsm_do_xsm_op (XEN_GUEST_HANDLE_PARAM(xsm_op_t) op) { return xsm_ops->do_xsm_op(op); diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c index e254251..22c66e5 100644 --- a/xen/xsm/dummy.c +++ b/xen/xsm/dummy.c @@ -94,6 +94,8 @@ void xsm_fixup_ops (struct xsm_operations *ops) set_to_dummy_if_null(ops, resource_setup_misc); set_to_dummy_if_null(ops, page_offline); + set_to_dummy_if_null(ops, tmem_op); + set_to_dummy_if_null(ops, tmem_control); set_to_dummy_if_null(ops, do_xsm_op); diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index f7309fd..222ab3e 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -1017,6 +1017,16 @@ static inline int flask_page_offline(uint32_t cmd) } } +static inline int flask_tmem_op(void) +{ + return domain_has_xen(current->domain, XEN__TMEM_OP); +} + +static inline int flask_tmem_control(void) +{ + return domain_has_xen(current->domain, XEN__TMEM_CONTROL); +} + #ifdef CONFIG_X86 static int flask_shadow_control(struct domain *d, uint32_t op) { @@ -1456,6 +1466,8 @@ static struct xsm_operations flask_ops = { .resource_setup_misc = flask_resource_setup_misc, .page_offline = flask_page_offline, + .tmem_op = flask_tmem_op, + .tmem_control = flask_tmem_control, .do_xsm_op = do_flask_op, diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors index caf65d2..7a7e253 100644 --- a/xen/xsm/flask/policy/access_vectors +++ b/xen/xsm/flask/policy/access_vectors @@ -35,6 +35,8 @@ class xen lockprof cpupool_op sched_op + tmem_op + tmem_control } class domain -- 1.7.11.7
Daniel De Graaf
2013-Jan-10 15:33 UTC
[PATCH 20/22] xen/xsm: distinguish scheduler get/set operations
Add getscheduler and setscheduler permissions to replace the monolithic scheduler permission in the scheduler_op domctl and sysctl. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Cc: George Dunlap <george.dunlap@eu.citrix.com> Cc: Keir Fraser <keir@xen.org> --- tools/flask/policy/policy/modules/xen/xen.if | 6 ++-- tools/flask/policy/policy/modules/xen/xen.te | 4 +-- xen/common/schedule.c | 10 ++++++- xen/include/xsm/dummy.h | 12 ++++++++ xen/include/xsm/xsm.h | 12 ++++++++ xen/xsm/dummy.c | 2 ++ xen/xsm/flask/hooks.c | 44 +++++++++++++++++++++++----- xen/xsm/flask/policy/access_vectors | 7 +++-- 8 files changed, 81 insertions(+), 16 deletions(-) diff --git a/tools/flask/policy/policy/modules/xen/xen.if b/tools/flask/policy/policy/modules/xen/xen.if index d9d5344..2ce2212 100644 --- a/tools/flask/policy/policy/modules/xen/xen.if +++ b/tools/flask/policy/policy/modules/xen/xen.if @@ -47,9 +47,9 @@ define(`declare_build_label'', ` define(`create_domain_common'', ` allow $1 $2:domain { create max_vcpus setdomainmaxmem setaddrsize getdomaininfo hypercall setvcpucontext setextvcpucontext - scheduler getvcpuinfo getvcpuextstate getaddrsize + getscheduler getvcpuinfo getvcpuextstate getaddrsize getvcpuaffinity setvcpuaffinity }; - allow $1 $2:domain2 { set_cpuid settsc }; + allow $1 $2:domain2 { set_cpuid settsc setscheduler }; allow $1 $2:security check_context; allow $1 $2:shadow enable; allow $1 $2:mmu { map_read map_write adjust memorymap physmap pinpage mmuext_op }; @@ -79,7 +79,7 @@ define(`create_domain_build_label'', ` define(`manage_domain'', ` allow $1 $2:domain { getdomaininfo getvcpuinfo getvcpuaffinity getaddrsize pause unpause trigger shutdown destroy - setvcpuaffinity setdomainmaxmem }; + setvcpuaffinity setdomainmaxmem getscheduler }; '') # migrate_domain_out(priv, target) diff --git a/tools/flask/policy/policy/modules/xen/xen.te b/tools/flask/policy/policy/modules/xen/xen.te index c714dcb..955fd8b 100644 --- a/tools/flask/policy/policy/modules/xen/xen.te +++ b/tools/flask/policy/policy/modules/xen/xen.te @@ -55,8 +55,8 @@ type device_t, resource_type; # ################################################################################ allow dom0_t xen_t:xen { kexec readapic writeapic mtrr_read mtrr_add mtrr_del - scheduler physinfo heap quirk readconsole writeconsole settime getcpuinfo - microcode cpupool_op sched_op pm_op tmem_control }; + physinfo heap quirk readconsole writeconsole settime getcpuinfo + microcode cpupool_op pm_op tmem_control getscheduler setscheduler }; allow dom0_t xen_t:mmu { memorymap }; allow dom0_t security_t:security { check_context compute_av compute_create compute_member load_policy compute_relabel compute_user setenforce diff --git a/xen/common/schedule.c b/xen/common/schedule.c index 903f32d..f3fc6bc 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -1006,7 +1006,11 @@ int sched_id(void) long sched_adjust(struct domain *d, struct xen_domctl_scheduler_op *op) { long ret; - + + ret = xsm_domctl_scheduler_op(XSM_HOOK, d, op->cmd); + if ( ret ) + return ret; + if ( (op->sched_id != DOM2OP(d)->sched_id) || ((op->cmd != XEN_DOMCTL_SCHEDOP_putinfo) && (op->cmd != XEN_DOMCTL_SCHEDOP_getinfo)) ) @@ -1025,6 +1029,10 @@ long sched_adjust_global(struct xen_sysctl_scheduler_op *op) struct cpupool *pool; int rc; + rc = xsm_sysctl_scheduler_op(XSM_HOOK, op->cmd); + if ( rc ) + return rc; + if ( (op->cmd != XEN_DOMCTL_SCHEDOP_putinfo) && (op->cmd != XEN_DOMCTL_SCHEDOP_getinfo) ) return -EINVAL; diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index 2c750de..18f36b2 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -95,6 +95,18 @@ static XSM_INLINE int xsm_getdomaininfo(XSM_DEFAULT_ARG struct domain *d) return xsm_default_action(action, current->domain, d); } +static XSM_INLINE int xsm_domctl_scheduler_op(XSM_DEFAULT_ARG struct domain *d, int cmd) +{ + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); +} + +static XSM_INLINE int xsm_sysctl_scheduler_op(XSM_DEFAULT_ARG int cmd) +{ + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, NULL); +} + static XSM_INLINE int xsm_set_target(XSM_DEFAULT_ARG struct domain *d, struct domain *e) { XSM_ASSERT_ACTION(XSM_HOOK); diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index ce5ede8..8947372 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -55,6 +55,8 @@ struct xsm_operations { struct xen_domctl_getdomaininfo *info); int (*domain_create) (struct domain *d, u32 ssidref); int (*getdomaininfo) (struct domain *d); + int (*domctl_scheduler_op) (struct domain *d, int op); + int (*sysctl_scheduler_op) (int op); int (*set_target) (struct domain *d, struct domain *e); int (*domctl) (struct domain *d, int cmd); int (*sysctl) (int cmd); @@ -177,6 +179,16 @@ static inline int xsm_getdomaininfo (xsm_default_t def, struct domain *d) return xsm_ops->getdomaininfo(d); } +static inline int xsm_domctl_scheduler_op (xsm_default_t def, struct domain *d, int cmd) +{ + return xsm_ops->domctl_scheduler_op(d, cmd); +} + +static inline int xsm_sysctl_scheduler_op (xsm_default_t def, int cmd) +{ + return xsm_ops->sysctl_scheduler_op(cmd); +} + static inline int xsm_set_target (xsm_default_t def, struct domain *d, struct domain *e) { return xsm_ops->set_target(d, e); diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c index 22c66e5..529a724 100644 --- a/xen/xsm/dummy.c +++ b/xen/xsm/dummy.c @@ -32,6 +32,8 @@ void xsm_fixup_ops (struct xsm_operations *ops) set_to_dummy_if_null(ops, security_domaininfo); set_to_dummy_if_null(ops, domain_create); set_to_dummy_if_null(ops, getdomaininfo); + set_to_dummy_if_null(ops, domctl_scheduler_op); + set_to_dummy_if_null(ops, sysctl_scheduler_op); set_to_dummy_if_null(ops, set_target); set_to_dummy_if_null(ops, domctl); set_to_dummy_if_null(ops, sysctl); diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index 222ab3e..ba67502 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -517,6 +517,38 @@ static int flask_getdomaininfo(struct domain *d) return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETDOMAININFO); } +static int flask_domctl_scheduler_op(struct domain *d, int op) +{ + switch ( op ) + { + case XEN_DOMCTL_SCHEDOP_putinfo: + return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__SETSCHEDULER); + + case XEN_DOMCTL_SCHEDOP_getinfo: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETSCHEDULER); + + default: + printk("flask_domctl_scheduler_op: Unknown op %d\n", op); + return -EPERM; + } +} + +static int flask_sysctl_scheduler_op(int op) +{ + switch ( op ) + { + case XEN_DOMCTL_SCHEDOP_putinfo: + return domain_has_xen(current->domain, XEN__SETSCHEDULER); + + case XEN_DOMCTL_SCHEDOP_getinfo: + return domain_has_xen(current->domain, XEN__GETSCHEDULER); + + default: + printk("flask_domctl_scheduler_op: Unknown op %d\n", op); + return -EPERM; + } +} + static int flask_set_target(struct domain *d, struct domain *t) { int rc; @@ -548,6 +580,7 @@ static int flask_domctl(struct domain *d, int cmd) /* These have individual XSM hooks (common/domctl.c) */ case XEN_DOMCTL_createdomain: case XEN_DOMCTL_getdomaininfo: + case XEN_DOMCTL_scheduler_op: case XEN_DOMCTL_irq_permission: case XEN_DOMCTL_iomem_permission: case XEN_DOMCTL_set_target: @@ -586,9 +619,6 @@ static int flask_domctl(struct domain *d, int cmd) case XEN_DOMCTL_resumedomain: return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__RESUME); - case XEN_DOMCTL_scheduler_op: - return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SCHEDULER); - case XEN_DOMCTL_max_vcpus: return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__MAX_VCPUS); @@ -704,6 +734,7 @@ static int flask_sysctl(int cmd) case XEN_SYSCTL_readconsole: case XEN_SYSCTL_getdomaininfolist: case XEN_SYSCTL_page_offline_op: + case XEN_SYSCTL_scheduler_op: #ifdef CONFIG_X86 case XEN_SYSCTL_cpu_hotplug: #endif @@ -713,7 +744,7 @@ static int flask_sysctl(int cmd) return domain_has_xen(current->domain, XEN__TBUFCONTROL); case XEN_SYSCTL_sched_id: - return domain_has_xen(current->domain, XEN__SCHEDULER); + return domain_has_xen(current->domain, XEN__GETSCHEDULER); case XEN_SYSCTL_perfc_op: return domain_has_xen(current->domain, XEN__PERFCONTROL); @@ -739,9 +770,6 @@ static int flask_sysctl(int cmd) case XEN_SYSCTL_cpupool_op: return domain_has_xen(current->domain, XEN__CPUPOOL_OP); - case XEN_SYSCTL_scheduler_op: - return domain_has_xen(current->domain, XEN__SCHED_OP); - case XEN_SYSCTL_physinfo: case XEN_SYSCTL_topologyinfo: case XEN_SYSCTL_numainfo: @@ -1408,6 +1436,8 @@ static struct xsm_operations flask_ops = { .security_domaininfo = flask_security_domaininfo, .domain_create = flask_domain_create, .getdomaininfo = flask_getdomaininfo, + .domctl_scheduler_op = flask_domctl_scheduler_op, + .sysctl_scheduler_op = flask_sysctl_scheduler_op, .set_target = flask_set_target, .domctl = flask_domctl, .sysctl = flask_sysctl, diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors index 7a7e253..b982cf5 100644 --- a/xen/xsm/flask/policy/access_vectors +++ b/xen/xsm/flask/policy/access_vectors @@ -5,7 +5,6 @@ class xen { - scheduler settime tbufcontrol readconsole @@ -34,9 +33,10 @@ class xen mca_op lockprof cpupool_op - sched_op tmem_op tmem_control + getscheduler + setscheduler } class domain @@ -51,7 +51,7 @@ class domain destroy setvcpuaffinity getvcpuaffinity - scheduler + getscheduler getdomaininfo getvcpuinfo getvcpucontext @@ -85,6 +85,7 @@ class domain2 set_cpuid gettsc settsc + setscheduler } class hvm -- 1.7.11.7
Daniel De Graaf
2013-Jan-10 15:33 UTC
[PATCH 21/22] xsm/flask: document the access vectors
This adds comments to the FLASK access_vectors file describing what operations each access vector controls and the meanings of the source and target fields in the permission check. This also makes the indentation of the file consistent; no functionality changes are made. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Cc: Keir Fraser <keir@xen.org> --- xen/xsm/flask/policy/access_vectors | 459 ++++++++++++++++++++++++++++-------- 1 file changed, 355 insertions(+), 104 deletions(-) diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors index b982cf5..d144333 100644 --- a/xen/xsm/flask/policy/access_vectors +++ b/xen/xsm/flask/policy/access_vectors @@ -3,189 +3,440 @@ # # class class_name { permission_name ... } +# Class xen consists of dom0-only operations dealing with the hypervisor itself. +# Unless otherwise specified, the source is the domain executing the hypercall, +# and the target is the xen initial sid (type xen_t). class xen { - settime - tbufcontrol - readconsole - clearconsole - perfcontrol - mtrr_add - mtrr_del - mtrr_read - microcode - physinfo - quirk +# XENPF_settime + settime +# XEN_SYSCTL_tbuf_op + tbufcontrol +# CONSOLEIO_read, XEN_SYSCTL_readconsole + readconsole +# XEN_SYSCTL_readconsole with clear=1 + clearconsole +# XEN_SYSCTL_perfc_op + perfcontrol +# XENPF_add_memtype + mtrr_add +# XENPF_del_memtype + mtrr_del +# XENPF_read_memtype + mtrr_read +# XENPF_microcode_update + microcode +# XEN_SYSCTL_physinfo, XEN_SYSCTL_topologyinfo, XEN_SYSCTL_numainfo + physinfo +# XENPF_platform_quirk + quirk +# CONSOLEIO_write writeconsole +# PHYSDEVOP_apic_read, PHYSDEVOP_alloc_irq_vector readapic +# PHYSDEVOP_apic_write writeapic +# Most XENOPROF_* privprofile +# XENOPROF_{init,enable_virq,disable_virq,get_buffer} nonprivprofile +# kexec hypercall kexec - firmware - sleep - frequency - getidle - debug - getcpuinfo - heap - pm_op - mca_op - lockprof - cpupool_op - tmem_op - tmem_control - getscheduler - setscheduler +# XENPF_firmware_info, XENPF_efi_runtime_call + firmware +# XENPF_enter_acpi_sleep + sleep +# XENPF_change_freq + frequency +# XENPF_getidletime + getidle +# XEN_SYSCTL_debug_keys + debug +# XEN_SYSCTL_getcpuinfo, XENPF_get_cpu_version, XENPF_get_cpuinfo + getcpuinfo +# XEN_SYSCTL_availheap + heap +# XEN_SYSCTL_get_pmstat, XEN_SYSCTL_pm_op, XENPF_set_processor_pminfo, +# XENPF_core_parking + pm_op +# mca hypercall + mca_op +# XEN_SYSCTL_lockprof_op + lockprof +# XEN_SYSCTL_cpupool_op + cpupool_op +# tmem hypercall (any access) + tmem_op +# TMEM_CONTROL command of tmem hypercall + tmem_control +# XEN_SYSCTL_scheduler_op with XEN_DOMCTL_SCHEDOP_getinfo, XEN_SYSCTL_sched_id + getscheduler +# XEN_SYSCTL_scheduler_op with XEN_DOMCTL_SCHEDOP_putinfo + setscheduler } +# Classes domain and domain2 consist of operations that a domain performs on +# another domain or on itself. Unless otherwise specified, the source is the +# domain executing the hypercall, and the target is the domain being operated on +# (which may result in a _self or _target type). +# +# transitions in class domain are used to produce the _self and _target types; +# see docs/misc/xsm-flask.txt and the example XSM policy for details. class domain { - setvcpucontext - pause - unpause +# XEN_DOMCTL_setvcpucontext + setvcpucontext +# XEN_DOMCTL_pausedomain + pause +# XEN_DOMCTL_unpausedomain + unpause +# XEN_DOMCTL_resumedomain resume +# XEN_DOMCTL_createdomain create +# checked in FLASK_RELABEL_DOMAIN for any relabel operation: +# source = the old label of the domain +# target = the new label of the domain +# see also the domain2 relabel{from,to,self} permissions transition +# XEN_DOMCTL_max_vcpus max_vcpus +# XEN_DOMCTL_destroydomain destroy +# XEN_DOMCTL_setvcpuaffinity setvcpuaffinity - getvcpuaffinity - getscheduler - getdomaininfo - getvcpuinfo - getvcpucontext - setdomainmaxmem - setdomainhandle - setdebugging - hypercall +# XEN_DOMCTL_getvcpuaffinity + getvcpuaffinity +# XEN_DOMCTL_scheduler_op with XEN_DOMCTL_SCHEDOP_getinfo + getscheduler +# XEN_DOMCTL_getdomaininfo, XEN_SYSCTL_getdomaininfolist + getdomaininfo +# XEN_DOMCTL_getvcpuinfo + getvcpuinfo +# XEN_DOMCTL_getvcpucontext + getvcpucontext +# XEN_DOMCTL_max_mem + setdomainmaxmem +# XEN_DOMCTL_setdomainhandle + setdomainhandle +# XEN_DOMCTL_setdebugging + setdebugging +# XEN_DOMCTL_hypercall_init + hypercall +# XEN_DOMCTL_settimeoffset settime +# checked in XEN_DOMCTL_set_target: +# source = the new device model domain +# target = the new target domain +# see also the domain2 make_priv_for and set_as_target checks set_target +# SCHEDOP_remote_shutdown shutdown +# XEN_DOMCTL_set{,_machine}_address_size setaddrsize +# XEN_DOMCTL_get{,_machine}_address_size getaddrsize - trigger - getextvcpucontext - setextvcpucontext - getvcpuextstate - setvcpuextstate - getpodtarget - setpodtarget - set_misc_info - set_virq_handler +# XEN_DOMCTL_sendtrigger + trigger +# XEN_DOMCTL_get_ext_vcpucontext + getextvcpucontext +# XEN_DOMCTL_set_ext_vcpucontext + setextvcpucontext +# XEN_DOMCTL_getvcpuextstate + getvcpuextstate +# XEN_DOMCTL_setvcpuextstate + setvcpuextstate +# XENMEM_get_pod_target + getpodtarget +# XENMEM_set_pod_target + setpodtarget +# XEN_DOMCTL_subscribe, XEN_DOMCTL_disable_migrate, +# XEN_DOMCTL_suppress_spurious_page_faults + set_misc_info +# XEN_DOMCTL_set_virq_handler + set_virq_handler } +# This is a continuation of class domain, since only 32 permissions can be +# defined per class class domain2 { - relabelfrom - relabelto - relabelself - make_priv_for - set_as_target - set_cpuid - gettsc - settsc - setscheduler +# checked in FLASK_RELABEL_DOMAIN with non-DOMID_SELF: +# source = the domain making the hypercall +# target = the old label of the domain being relabeled + relabelfrom +# checked in FLASK_RELABEL_DOMAIN with non-DOMID_SELF: +# source = the domain making the hypercall +# target = the new label of the domain being relabeled + relabelto +# checked in FLASK_RELABEL_DOMAIN, only with DOMID_SELF: +# source = the old label of the domain +# target = the new label of the domain +# see also domain__transition + relabelself +# checked in XEN_DOMCTL_set_target: +# source = the domain making the hypercall +# target = the new device model domain + make_priv_for +# checked in XEN_DOMCTL_set_target: +# source = the domain making the hypercall +# target = the new target domain + set_as_target +# XEN_DOMCTL_set_cpuid + set_cpuid +# XEN_DOMCTL_gettscinfo + gettsc +# XEN_DOMCTL_settscinfo + settsc +# XEN_DOMCTL_scheduler_op with XEN_DOMCTL_SCHEDOP_putinfo + setscheduler } +# Similar to class domain, but primarily contains domctls related to HVM domains class hvm { +# XEN_DOMCTL_sethvmcontext sethvmc +# XEN_DOMCTL_gethvmcontext, XEN_DOMCTL_gethvmcontext_partial gethvmc +# HVMOP_set_param setparam +# HVMOP_get_param getparam +# HVMOP_set_pci_intx_level (also needs hvmctl) pcilevel +# HVMOP_set_isa_irq_level irqlevel +# HVMOP_set_pci_link_route pciroute - bind_irq - cacheattr + bind_irq +# XEN_DOMCTL_pin_mem_cacheattr + cacheattr +# HVMOP_track_dirty_vram trackdirtyvram +# HVMOP_modified_memory, HVMOP_get_mem_type, HVMOP_set_mem_type, +# HVMOP_set_mem_access, HVMOP_get_mem_access, HVMOP_pagetable_dying, +# HVMOP_inject_trap hvmctl +# XEN_DOMCTL_set_access_required mem_event +# XEN_DOMCTL_mem_sharing_op and XENMEM_sharing_op_{share,add_physmap} with: +# source = the domain making the hypercall +# target = domain whose memory is being shared mem_sharing +# XEN_DOMCTL_audit_p2m audit_p2m +# HVMOP_inject_msi send_irq +# checked in XENMEM_sharing_op_{share,add_physmap} with: +# source = domain whose memory is being shared +# target = client domain share_mem } +# Class event describes event channels. Interdomain event channels have their +# own security label which is computed using a type transition between the +# source and target domains. Each endpoint has its own label, and the +# permission checks must pass on both endpoints for an event channel to be +# established. class event { - bind - send - status - notify - create +# when creating an interdomain event channel endpoint: +# source = event channel label +# target = remote domain the event channel binds to. This may be a _self or +# _target label if the endpoints are related as such. +# This permission is checked when creating an unbound event channel and when the +# interdomain event channel is established. + bind +# EVTCHNOP_send: +# source = domain sending the event +# target = event channel label + send +# EVTCHNOP_status; same as _send + status +# <unused> + notify +# when creating an interdomain event channel endpoint: +# source = the domain creating the channel (which might not be an endpoint) +# target = event channel label + create +# EVTCHNOP_reset: +# source = domain making the hypercall +# target = domain whose event channels are being reset reset } +# Class grant describes pages shared by grant mappings. Pages use the security +# label of their owning domain. class grant { - map_read - map_write - unmap - transfer - setup +# GNTTABOP_map_grant_ref with any access + map_read +# GNTTABOP_map_grant_ref with write access + map_write +# GNTTABOP_unmap_grant_ref + unmap +# GNTTABOP_transfer + transfer +# GNTTABOP_setup_table, GNTTABOP_get_status_frames (target is commonly _self) + setup +# GNTTABOP_copy copy +# GNTTABOP_query_size, GNTTABOP_get_version query } +# Class mmu describes pages of memory not accessed using grants. Permissions +# are checked using the domain ID used to access the page - the most common case +# is a domain''s own ID (the _self label). Using DOMID_IO in the map command to +# restrict the mapping to IO memory will result in the target being domio_t, and +# migration uses read-only mappings with a target of DOMID_XEN (domxen_t). class mmu { - map_read - map_write - pageinfo - pagelist +# checked when using mmu_update to map a page readably +# source = domain making the hypercall (which might not own the page table) +# target = domain whose pages are being mapped + map_read +# checked when using mmu_update to map a page writably +# source = domain making the hypercall +# target = domain whose pages are being mapped + map_write +# XEN_DOMCTL_getpageframeinfo* + pageinfo +# XEN_DOMCTL_getmemlist + pagelist +# XENMEM_{increase,decrease}_reservation, XENMEM_populate_physmap adjust +# XENMEM_{current,maximum}_reservation, XENMEM_maximum_gpfn stat +# <unused> translategp - updatemp +# mmu_update MMU_MACHPHYS_UPDATE + updatemp +# XENMEM_add_to_physmap, XENMEM_remove_from_physmap physmap +# MMUEXT_PIN_L*_TABLE pinpage +# <unused> mfnlist +# XENMEM_machine_memory_map (with target xen_t) +# XENMEM_set_memory_map (with domain target) memorymap +# checked when using mmu_update to update the page tables of another domain +# source = domain making the hypercall +# target = domain whose page tables are being modified remote_remap - mmuext_op - exchange +# the mmuext_op hypercall acting on the target domain + mmuext_op +# XENMEM_exchange: +# source = domain making the hypercall +# target = domain whose pages are being exchanged + exchange } +# control of the paging_domctl split by subop class shadow { - disable - enable +# XEN_DOMCTL_SHADOW_OP_OFF + disable +# enable, get/set allocation + enable +# enable, read, and clean log logdirty } +# Class resource is used to describe the resources used in hardware device +# passthrough. Resources include: hardware IRQs, MMIO regions, x86 I/O ports, +# and PCI devices; see docs/misc/xsm-flask.txt for how to label them. +# +# Access to the legacy PCI configuration space on x86 via port 0xCF8/CFC +# requires IS_PRIV, even with FLASK. Writes to the BARs are checked as "setup", +# while other reads/writes are "use"; the target is the PCI device whose +# configuration space is being modified. Accesses to the MMIO-based PCI express +# configuration space described by the ACPI MCFG table are controlled as MMIO +# accesses, and cannot special-case BAR writes. +# +# The {add,remove}_{irq,ioport,iomem,device} permissions use: +# source = domain making the hypercall +# target = resource''s security label class resource { - add - remove - use - add_irq - remove_irq - add_ioport - remove_ioport - add_iomem - remove_iomem - stat_device - add_device - remove_device - plug - unplug - setup +# checked when adding a resource to a domain: +# source = domain making the hypercall +# target = domain which will have access to the resource + add +# checked when removing a resource from a domain: +# source = domain making the hypercall +# target = domain which will no longer have access to the resource + remove +# checked when adding a resource to a domain: +# source = domain which will have access to the resource +# target = resource''s security label +# also checked when using some core Xen devices (target xen_t) + use +# PHYSDEVOP_map_pirq and ioapic writes for dom0 +# For GSI interrupts, the IRQ''s label is indexed by the IRQ number +# For MSI interrupts, the label of the PCI device is used + add_irq +# PHYSDEVOP_unmap_pirq: +# This is currently only checked for GSI interrupts + remove_irq +# XEN_DOMCTL_ioport_permission, XEN_DOMCTL_ioport_mapping + add_ioport + remove_ioport +# XEN_DOMCTL_iomem_permission, XEN_DOMCTL_memory_mapping + add_iomem + remove_iomem +# XEN_DOMCTL_get_device_group, XEN_DOMCTL_test_assign_device: +# source = domain making the hypercall +# target = PCI device being queried + stat_device +# XEN_DOMCTL_assign_device + add_device +# XEN_DOMCTL_deassign_device + remove_device +# checked for PCI hot and cold-plug hypercalls, with target as the PCI device +# checked for CPU and memory hotplug with xen_t as the target + plug +# checked for PCI hot-unplug hypercalls, with target as the PCI device +# checked for CPU offlining with xen_t as the target + unplug +# checked for PHYSDEVOP_restore_msi* (target PCI device) +# checked for PHYSDEVOP_setup_gsi (target IRQ) +# checked for PHYSDEVOP_pci_mmcfg_reserved (target xen_t) + setup } +# Class security describes the FLASK security server itself; these operations +# are accessed using the xsm_op hypercall. The source is the domain invoking +# the hypercall, and the target is security_t. +# +# Any domain with access to load_policy or setenforce must be trusted, since it +# can bypass the rest of the security policy. class security { - compute_av - compute_create - compute_member - check_context - load_policy - compute_relabel - compute_user - setenforce - setbool - setsecparam - add_ocontext - del_ocontext +# use the security server to compute an access check + compute_av +# use the security server to compute a type transition + compute_create +# use the security server to compute member selection + compute_member +# sid <-> context string conversions + check_context +# allow loading a new XSM/FLASK policy + load_policy +# use the security server to compute an object relabel + compute_relabel +# use the security server to list the SIDs reachable by a given user + compute_user +# allow switching between enforcing and permissive mode + setenforce +# allow changing policy booleans + setbool +# allow changing security server configuration parmeters + setsecparam +# add ocontext label definitions for resources + add_ocontext +# remove ocontext label definitions for resources + del_ocontext } -- 1.7.11.7
Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Cc: Keir Fraser <keir@xen.org> --- xen/xsm/flask/policy/access_vectors | 6 ------ 1 file changed, 6 deletions(-) diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors index d144333..2fdaede 100644 --- a/xen/xsm/flask/policy/access_vectors +++ b/xen/xsm/flask/policy/access_vectors @@ -254,8 +254,6 @@ class event send # EVTCHNOP_status; same as _send status -# <unused> - notify # when creating an interdomain event channel endpoint: # source = the domain creating the channel (which might not be an endpoint) # target = event channel label @@ -309,16 +307,12 @@ class mmu adjust # XENMEM_{current,maximum}_reservation, XENMEM_maximum_gpfn stat -# <unused> - translategp # mmu_update MMU_MACHPHYS_UPDATE updatemp # XENMEM_add_to_physmap, XENMEM_remove_from_physmap physmap # MMUEXT_PIN_L*_TABLE pinpage -# <unused> - mfnlist # XENMEM_machine_memory_map (with target xen_t) # XENMEM_set_memory_map (with domain target) memorymap -- 1.7.11.7
Ian Campbell
2013-Jan-11 12:04 UTC
Re: [PATCH v7 00/22] Merge IS_PRIV checks into XSM hooks
I see Keir has applied a bunch of these but now my builds are failing with: ld -melf_x86_64 -T xen.lds -N prelink.o \ /local/scratch/ianc/devel/committer.git/xen/common/symbols-dummy.o -o /local/scratch/ianc/devel/committer.git/xen/.xen-syms.0 prelink.o: In function `xsm_default_action'': /local/scratch/ianc/devel/committer.git/xen/include/xsm/dummy.h:75: undefined reference to `__xsm_action_mismatch_detected'' /local/scratch/ianc/devel/committer.git/xen/include/xsm/dummy.h:75: relocation truncated to fit: R_X86_64_PC32 against undefined symbol `__xsm_action_mismatch_detected'' /local/scratch/ianc/devel/committer.git/xen/include/xsm/dummy.h:75: undefined reference to `__xsm_action_mismatch_detected'' /local/scratch/ianc/devel/committer.git/xen/include/xsm/dummy.h:75: relocation truncated to fit: R_X86_64_PC32 against undefined symbol `__xsm_action_mismatch_detected'' [...lots more...] Ian.
Ian Campbell
2013-Jan-11 12:10 UTC
Re: [PATCH v7 00/22] Merge IS_PRIV checks into XSM hooks
On Fri, 2013-01-11 at 12:04 +0000, Ian Campbell wrote:> I see Keir has applied a bunch of these but now my builds are failing > with: > > ld -melf_x86_64 -T xen.lds -N prelink.o \ > /local/scratch/ianc/devel/committer.git/xen/common/symbols-dummy.o -o /local/scratch/ianc/devel/committer.git/xen/.xen-syms.0 > prelink.o: In function `xsm_default_action'': > /local/scratch/ianc/devel/committer.git/xen/include/xsm/dummy.h:75: undefined reference to `__xsm_action_mismatch_detected'' > /local/scratch/ianc/devel/committer.git/xen/include/xsm/dummy.h:75: relocation truncated to fit: R_X86_64_PC32 against undefined symbol `__xsm_action_mismatch_detected'' > /local/scratch/ianc/devel/committer.git/xen/include/xsm/dummy.h:75: undefined reference to `__xsm_action_mismatch_detected'' > /local/scratch/ianc/devel/committer.git/xen/include/xsm/dummy.h:75: relocation truncated to fit: R_X86_64_PC32 against undefined symbol `__xsm_action_mismatch_detected'' > [...lots more...]I should say that I''m not deliberately either enabling or disabling flask, so I''ll get the default (which is off?) Ian.
Keir Fraser
2013-Jan-11 13:27 UTC
Re: [PATCH v7 00/22] Merge IS_PRIV checks into XSM hooks
On 11/01/2013 12:04, "Ian Campbell" <Ian.Campbell@citrix.com> wrote:> I see Keir has applied a bunch of these but now my builds are failing > with: > > ld -melf_x86_64 -T xen.lds -N prelink.o \ > /local/scratch/ianc/devel/committer.git/xen/common/symbols-dummy.o -o > /local/scratch/ianc/devel/committer.git/xen/.xen-syms.0 > prelink.o: In function `xsm_default_action'': > /local/scratch/ianc/devel/committer.git/xen/include/xsm/dummy.h:75: undefined > reference to `__xsm_action_mismatch_detected'' > /local/scratch/ianc/devel/committer.git/xen/include/xsm/dummy.h:75: relocation > truncated to fit: R_X86_64_PC32 against undefined symbol > `__xsm_action_mismatch_detected'' > /local/scratch/ianc/devel/committer.git/xen/include/xsm/dummy.h:75: undefined > reference to `__xsm_action_mismatch_detected'' > /local/scratch/ianc/devel/committer.git/xen/include/xsm/dummy.h:75: relocation > truncated to fit: R_X86_64_PC32 against undefined symbol > `__xsm_action_mismatch_detected'' > [...lots more...]Was going to say it works for me, but it doesn''t! Must have not checked the last few patches, or not done a clean build. Hmm... -- Keir> Ian. > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > http://lists.xen.org/xen-devel
Keir Fraser
2013-Jan-11 13:47 UTC
Re: [PATCH v7 00/22] Merge IS_PRIV checks into XSM hooks
On 11/01/2013 12:04, "Ian Campbell" <Ian.Campbell@citrix.com> wrote:> I see Keir has applied a bunch of these but now my builds are failing > with:Should be fixed now. -- Keir> ld -melf_x86_64 -T xen.lds -N prelink.o \ > /local/scratch/ianc/devel/committer.git/xen/common/symbols-dummy.o -o > /local/scratch/ianc/devel/committer.git/xen/.xen-syms.0 > prelink.o: In function `xsm_default_action'': > /local/scratch/ianc/devel/committer.git/xen/include/xsm/dummy.h:75: undefined > reference to `__xsm_action_mismatch_detected'' > /local/scratch/ianc/devel/committer.git/xen/include/xsm/dummy.h:75: relocation > truncated to fit: R_X86_64_PC32 against undefined symbol > `__xsm_action_mismatch_detected'' > /local/scratch/ianc/devel/committer.git/xen/include/xsm/dummy.h:75: undefined > reference to `__xsm_action_mismatch_detected'' > /local/scratch/ianc/devel/committer.git/xen/include/xsm/dummy.h:75: relocation > truncated to fit: R_X86_64_PC32 against undefined symbol > `__xsm_action_mismatch_detected'' > [...lots more...] > > Ian. > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > http://lists.xen.org/xen-devel
George Dunlap
2013-Jan-15 16:50 UTC
Re: [PATCH 20/22] xen/xsm: distinguish scheduler get/set operations
On 10/01/13 15:33, Daniel De Graaf wrote:> Add getscheduler and setscheduler permissions to replace the monolithic > scheduler permission in the scheduler_op domctl and sysctl. > > Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> > Cc: George Dunlap <george.dunlap@eu.citrix.com> > Cc: Keir Fraser <keir@xen.org>Haven''t reviewed the code in detail, but in principle it sounds like a great idea: Acked-by: George Dunlap <george.dunlap@eu.citrix.com>> --- > tools/flask/policy/policy/modules/xen/xen.if | 6 ++-- > tools/flask/policy/policy/modules/xen/xen.te | 4 +-- > xen/common/schedule.c | 10 ++++++- > xen/include/xsm/dummy.h | 12 ++++++++ > xen/include/xsm/xsm.h | 12 ++++++++ > xen/xsm/dummy.c | 2 ++ > xen/xsm/flask/hooks.c | 44 +++++++++++++++++++++++----- > xen/xsm/flask/policy/access_vectors | 7 +++-- > 8 files changed, 81 insertions(+), 16 deletions(-) > > diff --git a/tools/flask/policy/policy/modules/xen/xen.if b/tools/flask/policy/policy/modules/xen/xen.if > index d9d5344..2ce2212 100644 > --- a/tools/flask/policy/policy/modules/xen/xen.if > +++ b/tools/flask/policy/policy/modules/xen/xen.if > @@ -47,9 +47,9 @@ define(`declare_build_label'', ` > define(`create_domain_common'', ` > allow $1 $2:domain { create max_vcpus setdomainmaxmem setaddrsize > getdomaininfo hypercall setvcpucontext setextvcpucontext > - scheduler getvcpuinfo getvcpuextstate getaddrsize > + getscheduler getvcpuinfo getvcpuextstate getaddrsize > getvcpuaffinity setvcpuaffinity }; > - allow $1 $2:domain2 { set_cpuid settsc }; > + allow $1 $2:domain2 { set_cpuid settsc setscheduler }; > allow $1 $2:security check_context; > allow $1 $2:shadow enable; > allow $1 $2:mmu { map_read map_write adjust memorymap physmap pinpage mmuext_op }; > @@ -79,7 +79,7 @@ define(`create_domain_build_label'', ` > define(`manage_domain'', ` > allow $1 $2:domain { getdomaininfo getvcpuinfo getvcpuaffinity > getaddrsize pause unpause trigger shutdown destroy > - setvcpuaffinity setdomainmaxmem }; > + setvcpuaffinity setdomainmaxmem getscheduler }; > '') > > # migrate_domain_out(priv, target) > diff --git a/tools/flask/policy/policy/modules/xen/xen.te b/tools/flask/policy/policy/modules/xen/xen.te > index c714dcb..955fd8b 100644 > --- a/tools/flask/policy/policy/modules/xen/xen.te > +++ b/tools/flask/policy/policy/modules/xen/xen.te > @@ -55,8 +55,8 @@ type device_t, resource_type; > # > ################################################################################ > allow dom0_t xen_t:xen { kexec readapic writeapic mtrr_read mtrr_add mtrr_del > - scheduler physinfo heap quirk readconsole writeconsole settime getcpuinfo > - microcode cpupool_op sched_op pm_op tmem_control }; > + physinfo heap quirk readconsole writeconsole settime getcpuinfo > + microcode cpupool_op pm_op tmem_control getscheduler setscheduler }; > allow dom0_t xen_t:mmu { memorymap }; > allow dom0_t security_t:security { check_context compute_av compute_create > compute_member load_policy compute_relabel compute_user setenforce > diff --git a/xen/common/schedule.c b/xen/common/schedule.c > index 903f32d..f3fc6bc 100644 > --- a/xen/common/schedule.c > +++ b/xen/common/schedule.c > @@ -1006,7 +1006,11 @@ int sched_id(void) > long sched_adjust(struct domain *d, struct xen_domctl_scheduler_op *op) > { > long ret; > - > + > + ret = xsm_domctl_scheduler_op(XSM_HOOK, d, op->cmd); > + if ( ret ) > + return ret; > + > if ( (op->sched_id != DOM2OP(d)->sched_id) || > ((op->cmd != XEN_DOMCTL_SCHEDOP_putinfo) && > (op->cmd != XEN_DOMCTL_SCHEDOP_getinfo)) ) > @@ -1025,6 +1029,10 @@ long sched_adjust_global(struct xen_sysctl_scheduler_op *op) > struct cpupool *pool; > int rc; > > + rc = xsm_sysctl_scheduler_op(XSM_HOOK, op->cmd); > + if ( rc ) > + return rc; > + > if ( (op->cmd != XEN_DOMCTL_SCHEDOP_putinfo) && > (op->cmd != XEN_DOMCTL_SCHEDOP_getinfo) ) > return -EINVAL; > diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h > index 2c750de..18f36b2 100644 > --- a/xen/include/xsm/dummy.h > +++ b/xen/include/xsm/dummy.h > @@ -95,6 +95,18 @@ static XSM_INLINE int xsm_getdomaininfo(XSM_DEFAULT_ARG struct domain *d) > return xsm_default_action(action, current->domain, d); > } > > +static XSM_INLINE int xsm_domctl_scheduler_op(XSM_DEFAULT_ARG struct domain *d, int cmd) > +{ > + XSM_ASSERT_ACTION(XSM_HOOK); > + return xsm_default_action(action, current->domain, d); > +} > + > +static XSM_INLINE int xsm_sysctl_scheduler_op(XSM_DEFAULT_ARG int cmd) > +{ > + XSM_ASSERT_ACTION(XSM_HOOK); > + return xsm_default_action(action, current->domain, NULL); > +} > + > static XSM_INLINE int xsm_set_target(XSM_DEFAULT_ARG struct domain *d, struct domain *e) > { > XSM_ASSERT_ACTION(XSM_HOOK); > diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h > index ce5ede8..8947372 100644 > --- a/xen/include/xsm/xsm.h > +++ b/xen/include/xsm/xsm.h > @@ -55,6 +55,8 @@ struct xsm_operations { > struct xen_domctl_getdomaininfo *info); > int (*domain_create) (struct domain *d, u32 ssidref); > int (*getdomaininfo) (struct domain *d); > + int (*domctl_scheduler_op) (struct domain *d, int op); > + int (*sysctl_scheduler_op) (int op); > int (*set_target) (struct domain *d, struct domain *e); > int (*domctl) (struct domain *d, int cmd); > int (*sysctl) (int cmd); > @@ -177,6 +179,16 @@ static inline int xsm_getdomaininfo (xsm_default_t def, struct domain *d) > return xsm_ops->getdomaininfo(d); > } > > +static inline int xsm_domctl_scheduler_op (xsm_default_t def, struct domain *d, int cmd) > +{ > + return xsm_ops->domctl_scheduler_op(d, cmd); > +} > + > +static inline int xsm_sysctl_scheduler_op (xsm_default_t def, int cmd) > +{ > + return xsm_ops->sysctl_scheduler_op(cmd); > +} > + > static inline int xsm_set_target (xsm_default_t def, struct domain *d, struct domain *e) > { > return xsm_ops->set_target(d, e); > diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c > index 22c66e5..529a724 100644 > --- a/xen/xsm/dummy.c > +++ b/xen/xsm/dummy.c > @@ -32,6 +32,8 @@ void xsm_fixup_ops (struct xsm_operations *ops) > set_to_dummy_if_null(ops, security_domaininfo); > set_to_dummy_if_null(ops, domain_create); > set_to_dummy_if_null(ops, getdomaininfo); > + set_to_dummy_if_null(ops, domctl_scheduler_op); > + set_to_dummy_if_null(ops, sysctl_scheduler_op); > set_to_dummy_if_null(ops, set_target); > set_to_dummy_if_null(ops, domctl); > set_to_dummy_if_null(ops, sysctl); > diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c > index 222ab3e..ba67502 100644 > --- a/xen/xsm/flask/hooks.c > +++ b/xen/xsm/flask/hooks.c > @@ -517,6 +517,38 @@ static int flask_getdomaininfo(struct domain *d) > return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETDOMAININFO); > } > > +static int flask_domctl_scheduler_op(struct domain *d, int op) > +{ > + switch ( op ) > + { > + case XEN_DOMCTL_SCHEDOP_putinfo: > + return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__SETSCHEDULER); > + > + case XEN_DOMCTL_SCHEDOP_getinfo: > + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETSCHEDULER); > + > + default: > + printk("flask_domctl_scheduler_op: Unknown op %d\n", op); > + return -EPERM; > + } > +} > + > +static int flask_sysctl_scheduler_op(int op) > +{ > + switch ( op ) > + { > + case XEN_DOMCTL_SCHEDOP_putinfo: > + return domain_has_xen(current->domain, XEN__SETSCHEDULER); > + > + case XEN_DOMCTL_SCHEDOP_getinfo: > + return domain_has_xen(current->domain, XEN__GETSCHEDULER); > + > + default: > + printk("flask_domctl_scheduler_op: Unknown op %d\n", op); > + return -EPERM; > + } > +} > + > static int flask_set_target(struct domain *d, struct domain *t) > { > int rc; > @@ -548,6 +580,7 @@ static int flask_domctl(struct domain *d, int cmd) > /* These have individual XSM hooks (common/domctl.c) */ > case XEN_DOMCTL_createdomain: > case XEN_DOMCTL_getdomaininfo: > + case XEN_DOMCTL_scheduler_op: > case XEN_DOMCTL_irq_permission: > case XEN_DOMCTL_iomem_permission: > case XEN_DOMCTL_set_target: > @@ -586,9 +619,6 @@ static int flask_domctl(struct domain *d, int cmd) > case XEN_DOMCTL_resumedomain: > return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__RESUME); > > - case XEN_DOMCTL_scheduler_op: > - return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SCHEDULER); > - > case XEN_DOMCTL_max_vcpus: > return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__MAX_VCPUS); > > @@ -704,6 +734,7 @@ static int flask_sysctl(int cmd) > case XEN_SYSCTL_readconsole: > case XEN_SYSCTL_getdomaininfolist: > case XEN_SYSCTL_page_offline_op: > + case XEN_SYSCTL_scheduler_op: > #ifdef CONFIG_X86 > case XEN_SYSCTL_cpu_hotplug: > #endif > @@ -713,7 +744,7 @@ static int flask_sysctl(int cmd) > return domain_has_xen(current->domain, XEN__TBUFCONTROL); > > case XEN_SYSCTL_sched_id: > - return domain_has_xen(current->domain, XEN__SCHEDULER); > + return domain_has_xen(current->domain, XEN__GETSCHEDULER); > > case XEN_SYSCTL_perfc_op: > return domain_has_xen(current->domain, XEN__PERFCONTROL); > @@ -739,9 +770,6 @@ static int flask_sysctl(int cmd) > case XEN_SYSCTL_cpupool_op: > return domain_has_xen(current->domain, XEN__CPUPOOL_OP); > > - case XEN_SYSCTL_scheduler_op: > - return domain_has_xen(current->domain, XEN__SCHED_OP); > - > case XEN_SYSCTL_physinfo: > case XEN_SYSCTL_topologyinfo: > case XEN_SYSCTL_numainfo: > @@ -1408,6 +1436,8 @@ static struct xsm_operations flask_ops = { > .security_domaininfo = flask_security_domaininfo, > .domain_create = flask_domain_create, > .getdomaininfo = flask_getdomaininfo, > + .domctl_scheduler_op = flask_domctl_scheduler_op, > + .sysctl_scheduler_op = flask_sysctl_scheduler_op, > .set_target = flask_set_target, > .domctl = flask_domctl, > .sysctl = flask_sysctl, > diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors > index 7a7e253..b982cf5 100644 > --- a/xen/xsm/flask/policy/access_vectors > +++ b/xen/xsm/flask/policy/access_vectors > @@ -5,7 +5,6 @@ > > class xen > { > - scheduler > settime > tbufcontrol > readconsole > @@ -34,9 +33,10 @@ class xen > mca_op > lockprof > cpupool_op > - sched_op > tmem_op > tmem_control > + getscheduler > + setscheduler > } > > class domain > @@ -51,7 +51,7 @@ class domain > destroy > setvcpuaffinity > getvcpuaffinity > - scheduler > + getscheduler > getdomaininfo > getvcpuinfo > getvcpucontext > @@ -85,6 +85,7 @@ class domain2 > set_cpuid > gettsc > settsc > + setscheduler > } > > class hvm