From mboxrd@z Thu Jan 1 00:00:00 1970 From: Daniel De Graaf Subject: Re: [RFC 05/14] xen/xsm: xsm functions for PCI passthrough is not x86 specific Date: Thu, 13 Mar 2014 10:25:39 -0400 Message-ID: <5321BFE3.40905@tycho.nsa.gov> References: <1394640969-25583-1-git-send-email-julien.grall@linaro.org> <1394640969-25583-6-git-send-email-julien.grall@linaro.org> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii"; Format="flowed" Content-Transfer-Encoding: 7bit Return-path: Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1WO6aY-0004ds-FI for xen-devel@lists.xenproject.org; Thu, 13 Mar 2014 14:26:26 +0000 In-Reply-To: <1394640969-25583-6-git-send-email-julien.grall@linaro.org> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Julien Grall , xen-devel@lists.xenproject.org Cc: stefano.stabellini@citrix.com, tim@xen.org, ian.campbell@citrix.com List-Id: xen-devel@lists.xenproject.org On 03/12/2014 12:16 PM, Julien Grall wrote: > Protect xsm functions for PCI passthrough by HAS_PASSTHROUGH && HAS_PCI > > Signed-off-by: Julien Grall > Cc: Daniel De Graaf Acked-by: Daniel De Graaf > --- > xen/include/xsm/dummy.h | 3 + > xen/include/xsm/xsm.h | 4 ++ > xen/xsm/dummy.c | 2 + > xen/xsm/flask/hooks.c | 143 +++++++++++++++++++++++++---------------------- > 4 files changed, 84 insertions(+), 68 deletions(-) > > diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h > index 3bcd941..76f9280 100644 > --- a/xen/include/xsm/dummy.h > +++ b/xen/include/xsm/dummy.h > @@ -317,6 +317,7 @@ static XSM_INLINE int xsm_set_pod_target(XSM_DEFAULT_ARG struct domain *d) > return xsm_default_action(action, current->domain, d); > } > > +#if defined(HAS_PASSTHROUGH) && defined(HAS_PCI) > static XSM_INLINE int xsm_get_device_group(XSM_DEFAULT_ARG uint32_t machine_bdf) > { > XSM_ASSERT_ACTION(XSM_HOOK); > @@ -341,6 +342,8 @@ static XSM_INLINE int xsm_deassign_device(XSM_DEFAULT_ARG struct domain *d, uint > return xsm_default_action(action, current->domain, d); > } > > +#endif /* HAS_PASSTHROUGH && HAS_PCI */ > + > static XSM_INLINE int xsm_resource_plug_core(XSM_DEFAULT_VOID) > { > XSM_ASSERT_ACTION(XSM_HOOK); > diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h > index de9cf86..11218b6 100644 > --- a/xen/include/xsm/xsm.h > +++ b/xen/include/xsm/xsm.h > @@ -111,10 +111,12 @@ struct xsm_operations { > 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); > > +#if defined(HAS_PASSTHROUGH) && defined(HAS_PCI) > int (*get_device_group) (uint32_t machine_bdf); > int (*test_assign_device) (uint32_t machine_bdf); > int (*assign_device) (struct domain *d, uint32_t machine_bdf); > int (*deassign_device) (struct domain *d, uint32_t machine_bdf); > +#endif > > int (*resource_plug_core) (void); > int (*resource_unplug_core) (void); > @@ -427,6 +429,7 @@ static inline int xsm_pci_config_permission (xsm_default_t def, struct domain *d > return xsm_ops->pci_config_permission(d, machine_bdf, start, end, access); > } > > +#if defined(HAS_PASSTHROUGH) && defined(HAS_PCI) > static inline int xsm_get_device_group(xsm_default_t def, uint32_t machine_bdf) > { > return xsm_ops->get_device_group(machine_bdf); > @@ -446,6 +449,7 @@ static inline int xsm_deassign_device(xsm_default_t def, struct domain *d, uint3 > { > return xsm_ops->deassign_device(d, machine_bdf); > } > +#endif /* HAS_PASSTHROUGH && HAS_PCI) */ > > static inline int xsm_resource_plug_pci (xsm_default_t def, uint32_t machine_bdf) > { > diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c > index 3fe4c59..627edcc 100644 > --- a/xen/xsm/dummy.c > +++ b/xen/xsm/dummy.c > @@ -85,10 +85,12 @@ void xsm_fixup_ops (struct xsm_operations *ops) > set_to_dummy_if_null(ops, iomem_mapping); > set_to_dummy_if_null(ops, pci_config_permission); > > +#if defined(HAS_PASSTHROUGH) && defined(HAS_PCI) > set_to_dummy_if_null(ops, get_device_group); > set_to_dummy_if_null(ops, test_assign_device); > set_to_dummy_if_null(ops, assign_device); > set_to_dummy_if_null(ops, deassign_device); > +#endif > > set_to_dummy_if_null(ops, resource_plug_core); > set_to_dummy_if_null(ops, resource_unplug_core); > diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c > index 96276ac..7329f31 100644 > --- a/xen/xsm/flask/hooks.c > +++ b/xen/xsm/flask/hooks.c > @@ -1102,6 +1102,72 @@ static int flask_hvm_param_nested(struct domain *d) > return current_has_perm(d, SECCLASS_HVM, HVM__NESTED); > } > > +#if defined(HAS_PASSTHROUGH) && defined(HAS_PCI) > +static int flask_get_device_group(uint32_t machine_bdf) > +{ > + u32 rsid; > + int rc = -EPERM; > + > + rc = security_device_sid(machine_bdf, &rsid); > + if ( rc ) > + return rc; > + > + 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; > + > + rc = security_device_sid(machine_bdf, &rsid); > + if ( rc ) > + return rc; > + > + 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 dsid, rsid; > + int rc = -EPERM; > + struct avc_audit_data ad; > + > + rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__ADD); > + if ( rc ) > + return rc; > + > + rc = security_device_sid(machine_bdf, &rsid); > + if ( rc ) > + return rc; > + > + AVC_AUDIT_DATA_INIT(&ad, DEV); > + ad.device = (unsigned long) machine_bdf; > + rc = avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__ADD_DEVICE, &ad); > + if ( rc ) > + return rc; > + > + 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; > + > + rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__REMOVE); > + if ( rc ) > + return rc; > + > + rc = security_device_sid(machine_bdf, &rsid); > + if ( rc ) > + return rc; > + > + return avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__REMOVE_DEVICE, NULL); > +} > +#endif /* HAS_PASSTHROUGH && HAS_PCI */ > + > #ifdef CONFIG_X86 > static int flask_shadow_control(struct domain *d, uint32_t op) > { > @@ -1355,70 +1421,6 @@ static int flask_priv_mapping(struct domain *d, struct domain *t) > return domain_has_perm(d, t, SECCLASS_MMU, MMU__TARGET_HACK); > } > > -static int flask_get_device_group(uint32_t machine_bdf) > -{ > - u32 rsid; > - int rc = -EPERM; > - > - rc = security_device_sid(machine_bdf, &rsid); > - if ( rc ) > - return rc; > - > - 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; > - > - rc = security_device_sid(machine_bdf, &rsid); > - if ( rc ) > - return rc; > - > - 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 dsid, rsid; > - int rc = -EPERM; > - struct avc_audit_data ad; > - > - rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__ADD); > - if ( rc ) > - return rc; > - > - rc = security_device_sid(machine_bdf, &rsid); > - if ( rc ) > - return rc; > - > - AVC_AUDIT_DATA_INIT(&ad, DEV); > - ad.device = (unsigned long) machine_bdf; > - rc = avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__ADD_DEVICE, &ad); > - if ( rc ) > - return rc; > - > - 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; > - > - rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__REMOVE); > - if ( rc ) > - return rc; > - > - rc = security_device_sid(machine_bdf, &rsid); > - if ( rc ) > - return rc; > - > - 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 dsid, rsid; > @@ -1540,6 +1542,14 @@ static struct xsm_operations flask_ops = { > .add_to_physmap = flask_add_to_physmap, > .remove_from_physmap = flask_remove_from_physmap, > > + > +#if defined(HAS_PASSTHROUGH) && defined(HAS_PCI) > + .get_device_group = flask_get_device_group, > + .test_assign_device = flask_test_assign_device, > + .assign_device = flask_assign_device, > + .deassign_device = flask_deassign_device, > +#endif > + > #ifdef CONFIG_X86 > .shadow_control = flask_shadow_control, > .hvm_set_pci_intx_level = flask_hvm_set_pci_intx_level, > @@ -1557,15 +1567,12 @@ static struct xsm_operations flask_ops = { > .mmuext_op = flask_mmuext_op, > .update_va_mapping = flask_update_va_mapping, > .priv_mapping = flask_priv_mapping, > - .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, > .ioport_permission = flask_ioport_permission, > .ioport_mapping = flask_ioport_mapping, > #endif > + > #ifdef CONFIG_ARM > .map_gmfn_foreign = flask_map_gmfn_foreign, > #endif > -- Daniel De Graaf National Security Agency