[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v2 04/17] xen: Introduce XEN_DOMCTL_CDF_not_hypercall_target
Add a new create domain flag to indicate if a domain can be the target of hypercalls. By default all domains can be targetted - subject to any other permission checks. This property is useful in a safety environment to isolate domains for freedom from interference. Signed-off-by: Jason Andryuk <jason.andryuk@xxxxxxx> --- DOMAIN_CAPS_NOT_HYPERCALL_TARGET duplicates the hypercall-untargetable DT property, so it could be removed. Leaving it here for now to at least illustrate the alternate approach. --- docs/misc/arm/device-tree/booting.txt | 6 ++++++ tools/ocaml/libs/xc/xenctrl.ml | 1 + tools/ocaml/libs/xc/xenctrl.mli | 1 + xen/arch/arm/domain.c | 3 ++- xen/common/device-tree/dom0less-build.c | 6 ++++++ xen/common/domain.c | 2 +- xen/include/public/bootfdt.h | 10 ++++++++-- xen/include/public/domctl.h | 4 +++- xen/include/xen/sched.h | 12 ++++++++++++ xen/include/xsm/dummy.h | 4 ++++ 10 files changed, 44 insertions(+), 5 deletions(-) diff --git a/docs/misc/arm/device-tree/booting.txt b/docs/misc/arm/device-tree/booting.txt index 07acc7ba64..963dd81912 100644 --- a/docs/misc/arm/device-tree/booting.txt +++ b/docs/misc/arm/device-tree/booting.txt @@ -307,6 +307,12 @@ with the following properties: passed through. This option is the default if this property is missing and the user does not provide the device partial device tree for the domain. +- hypercall-untargetable + + Optional. An empty property to specify the domain cannot be the target + of hypercalls. This protects a domain for freedom of interference from + other domains. + Under the "xen,domain" compatible node, one or more sub-nodes are present for the DomU kernel and ramdisk. diff --git a/tools/ocaml/libs/xc/xenctrl.ml b/tools/ocaml/libs/xc/xenctrl.ml index f5835e7d95..00c29199dc 100644 --- a/tools/ocaml/libs/xc/xenctrl.ml +++ b/tools/ocaml/libs/xc/xenctrl.ml @@ -72,6 +72,7 @@ type domain_create_flag = | CDF_VPMU | CDF_TRAP_UNMAPPED_ACCESSES | CDF_DEVICE_MODEL + | CDF_NOT_HYPERCALL_TARGET type domain_create_iommu_opts = | IOMMU_NO_SHAREPT diff --git a/tools/ocaml/libs/xc/xenctrl.mli b/tools/ocaml/libs/xc/xenctrl.mli index b9471a56a8..daf6686f4d 100644 --- a/tools/ocaml/libs/xc/xenctrl.mli +++ b/tools/ocaml/libs/xc/xenctrl.mli @@ -65,6 +65,7 @@ type domain_create_flag = | CDF_VPMU | CDF_TRAP_UNMAPPED_ACCESSES | CDF_DEVICE_MODEL + | CDF_NOT_HYPERCALL_TARGET type domain_create_iommu_opts = | IOMMU_NO_SHAREPT diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c index 57eecbd250..5f6358096f 100644 --- a/xen/arch/arm/domain.c +++ b/xen/arch/arm/domain.c @@ -614,7 +614,8 @@ int arch_sanitise_domain_config(struct xen_domctl_createdomain *config) unsigned int flags_optional = (XEN_DOMCTL_CDF_iommu | XEN_DOMCTL_CDF_vpmu | XEN_DOMCTL_CDF_xs_domain | XEN_DOMCTL_CDF_trap_unmapped_accesses | - XEN_DOMCTL_CDF_device_model); + XEN_DOMCTL_CDF_device_model | + XEN_DOMCTL_CDF_not_hypercall_target); unsigned int sve_vl_bits = sve_decode_vl(config->arch.sve_vl); if ( (config->flags & ~flags_optional) != flags_required ) diff --git a/xen/common/device-tree/dom0less-build.c b/xen/common/device-tree/dom0less-build.c index bb52291dfb..22af043aa5 100644 --- a/xen/common/device-tree/dom0less-build.c +++ b/xen/common/device-tree/dom0less-build.c @@ -886,6 +886,9 @@ void __init create_domUs(void) if ( val & DOMAIN_CAPS_DEVICE_MODEL ) d_cfg.flags |= XEN_DOMCTL_CDF_device_model; + + if ( val & DOMAIN_CAPS_NOT_HYPERCALL_TARGET ) + d_cfg.flags |= XEN_DOMCTL_CDF_not_hypercall_target; } if ( dt_find_property(node, "xen,static-mem", NULL) ) @@ -896,6 +899,9 @@ void __init create_domUs(void) flags |= CDF_staticmem; } + if ( dt_property_read_bool(node, "hypercall-untargetable") ) + d_cfg.flags |= XEN_DOMCTL_CDF_not_hypercall_target; + if ( dt_property_read_bool(node, "direct-map") ) { if ( !(flags & CDF_staticmem) ) diff --git a/xen/common/domain.c b/xen/common/domain.c index 42c590b8d7..c347de4335 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -723,7 +723,7 @@ static int sanitise_domain_config(struct xen_domctl_createdomain *config) XEN_DOMCTL_CDF_xs_domain | XEN_DOMCTL_CDF_iommu | XEN_DOMCTL_CDF_nested_virt | XEN_DOMCTL_CDF_vpmu | XEN_DOMCTL_CDF_trap_unmapped_accesses | - XEN_DOMCTL_CDF_device_model) ) + XEN_DOMCTL_CDF_device_model | XEN_DOMCTL_CDF_not_hypercall_target) ) { dprintk(XENLOG_INFO, "Unknown CDF flags %#x\n", config->flags); return -EINVAL; diff --git a/xen/include/public/bootfdt.h b/xen/include/public/bootfdt.h index c6b5afc76a..1eba1cc487 100644 --- a/xen/include/public/bootfdt.h +++ b/xen/include/public/bootfdt.h @@ -32,8 +32,14 @@ * Hardware domain for running QEMU. */ #define DOMAIN_CAPS_DEVICE_MODEL (1U << 3) +/* + * Domain cannot be the target of hypercalls. This provides the domain + * freedom from interference from other domains. + */ +#define DOMAIN_CAPS_NOT_HYPERCALL_TARGET (1U << 4) -#define DOMAIN_CAPS_MASK (DOMAIN_CAPS_CONTROL | DOMAIN_CAPS_HARDWARE | \ - DOMAIN_CAPS_XENSTORE | DOMAIN_CAPS_DEVICE_MODEL ) +#define DOMAIN_CAPS_MASK (DOMAIN_CAPS_CONTROL | DOMAIN_CAPS_HARDWARE | \ + DOMAIN_CAPS_XENSTORE | DOMAIN_CAPS_DEVICE_MODEL | \ + DOMAIN_CAPS_NOT_HYPERCALL_TARGET) #endif /* __XEN_PUBLIC_BOOTFDT_H__ */ diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h index 88a294c5be..f1f6f96bc2 100644 --- a/xen/include/public/domctl.h +++ b/xen/include/public/domctl.h @@ -70,9 +70,11 @@ struct xen_domctl_createdomain { #define XEN_DOMCTL_CDF_trap_unmapped_accesses (1U << 8) /* Allow domain to provide device model for multiple other domains */ #define XEN_DOMCTL_CDF_device_model (1U << 9) +/* Domain cannot be the target of hypercalls */ +#define XEN_DOMCTL_CDF_not_hypercall_target (1U << 10) /* Max XEN_DOMCTL_CDF_* constant. Used for ABI checking. */ -#define XEN_DOMCTL_CDF_MAX XEN_DOMCTL_CDF_device_model +#define XEN_DOMCTL_CDF_MAX XEN_DOMCTL_CDF_not_hypercall_target uint32_t flags; diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 9863603d93..8a32f9a1b6 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -1157,6 +1157,18 @@ static always_inline bool is_dm_domain(const struct domain *d) return evaluate_nospec(d->options & XEN_DOMCTL_CDF_device_model); } +/* + * Return whether this domain can be the target of hypercalls from other + * domains. + */ +static always_inline bool is_hypercall_target(const struct domain *d) +{ + if ( IS_ENABLED(CONFIG_PV_SHIM_EXCLUSIVE) ) + return true; + + return evaluate_nospec(!(d->options & XEN_DOMCTL_CDF_not_hypercall_target)); +} + #define VM_ASSIST(d, t) (test_bit(VMASST_TYPE_ ## t, &(d)->vm_assist)) static always_inline bool is_pv_domain(const struct domain *d) diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index 0b341efd18..f2205575ed 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -91,12 +91,16 @@ static always_inline int xsm_default_action( return 0; fallthrough; case XSM_DM_PRIV: + if ( target && !is_hypercall_target(target) ) + return -EPERM; if ( is_dm_domain(src) ) return 0; if ( target && evaluate_nospec(src->target == target) ) return 0; fallthrough; case XSM_PRIV: + if ( target && !is_hypercall_target(target) ) + return -EPERM; if ( is_control_domain(src) ) return 0; return -EPERM; -- 2.50.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |