[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] xen/arch/x86: complete XSM hooks on irq/pirq mappings


  • To: xen-changelog@xxxxxxxxxxxxxxxxxxx
  • From: Xen patchbot-unstable <patchbot@xxxxxxx>
  • Date: Mon, 04 Feb 2013 15:44:07 +0000
  • Delivery-date: Mon, 04 Feb 2013 15:44:27 +0000
  • List-id: "Change log for Mercurial \(receive only\)" <xen-changelog.lists.xen.org>

# HG changeset patch
# User Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
# Date 1358932730 0
# Node ID 7c6ecf2c1831a1c7f63a96f119a8891891463e54
# Parent  07d6d8bee6d752d1e662bf274b75b0b0979ea575
xen/arch/x86: complete XSM hooks on irq/pirq mappings

Manipulation of a domain's pirq namespace was not fully protected by
XSM hooks because the XSM hooks for IRQs needed a physical IRQ.  Since
this may not apply to HVM domains, a complete solution needs to split
the XSM hook for this operation, using one hook for the PIRQ
manipulation and one for controlling access to the hardware IRQ.

This reworking has the advantage of providing the same MSI data to
remove_irq that is provided to add_irq, allowing the PCI device to be
determined in both functions.  It also eliminates the last callers of
rcu_lock_target_domain_by_id in x86 and common code in preparation for
this function's removal.

Signed-off-by: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
Committed-by: Keir Fraser <keir@xxxxxxx>
---


diff -r 07d6d8bee6d7 -r 7c6ecf2c1831 xen/arch/x86/irq.c
--- a/xen/arch/x86/irq.c        Wed Jan 23 09:17:19 2013 +0000
+++ b/xen/arch/x86/irq.c        Wed Jan 23 09:18:50 2013 +0000
@@ -1874,7 +1874,7 @@ int map_domain_pirq(
         return 0;
     }
 
-    ret = xsm_map_domain_pirq(XSM_HOOK, d, irq, data);
+    ret = xsm_map_domain_irq(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",
@@ -1978,14 +1978,19 @@ int unmap_domain_pirq(struct domain *d, 
         goto done;
     }
 
+    desc = irq_to_desc(irq);
+    msi_desc = desc->msi_desc;
+
+    ret = xsm_unmap_domain_irq(XSM_HOOK, d, irq, msi_desc);
+    if ( ret )
+        goto done;
+
     forced_unbind = pirq_guest_force_unbind(d, info);
     if ( forced_unbind )
         dprintk(XENLOG_G_WARNING, "dom%d: forcing unbind of pirq %d\n",
                 d->domain_id, pirq);
 
-    desc = irq_to_desc(irq);
-
-    if ( (msi_desc = desc->msi_desc) != NULL )
+    if ( msi_desc != NULL )
         pci_disable_msi(msi_desc);
 
     spin_lock_irqsave(&desc->lock, flags);
diff -r 07d6d8bee6d7 -r 7c6ecf2c1831 xen/arch/x86/physdev.c
--- a/xen/arch/x86/physdev.c    Wed Jan 23 09:17:19 2013 +0000
+++ b/xen/arch/x86/physdev.c    Wed Jan 23 09:18:50 2013 +0000
@@ -105,7 +105,11 @@ int physdev_map_pirq(domid_t domid, int 
         return physdev_hvm_map_pirq(d, type, index, pirq_p);
     }
 
-    ret = rcu_lock_target_domain_by_id(domid, &d);
+    d = rcu_lock_domain_by_any_id(domid);
+    if ( d == NULL )
+        return -ESRCH;
+
+    ret = xsm_map_domain_pirq(XSM_TARGET, d);
     if ( ret )
         return ret;
 
@@ -218,9 +222,13 @@ int physdev_unmap_pirq(domid_t domid, in
     struct domain *d;
     int ret;
 
-    ret = rcu_lock_target_domain_by_id(domid, &d);
+    d = rcu_lock_domain_by_any_id(domid);
+    if ( d == NULL )
+        return -ESRCH;
+
+    ret = xsm_unmap_domain_pirq(XSM_TARGET, d);
     if ( ret )
-        return ret;
+        goto free_domain;
 
     if ( is_hvm_domain(d) )
     {
@@ -232,10 +240,6 @@ int physdev_unmap_pirq(domid_t domid, in
             goto free_domain;
     }
 
-    ret = xsm_unmap_domain_pirq(XSM_TARGET, d, domain_pirq_to_irq(d, pirq));
-    if ( ret )
-        goto free_domain;
-
     spin_lock(&pcidevs_lock);
     spin_lock(&d->event_lock);
     ret = unmap_domain_pirq(d, pirq);
diff -r 07d6d8bee6d7 -r 7c6ecf2c1831 xen/include/xsm/dummy.h
--- a/xen/include/xsm/dummy.h   Wed Jan 23 09:17:19 2013 +0000
+++ b/xen/include/xsm/dummy.h   Wed Jan 23 09:18:50 2013 +0000
@@ -405,18 +405,30 @@ static XSM_INLINE char *xsm_show_irq_sid
     return NULL;
 }
 
-static XSM_INLINE int xsm_map_domain_pirq(XSM_DEFAULT_ARG struct domain *d, 
int irq, void *data)
+static XSM_INLINE int xsm_map_domain_pirq(XSM_DEFAULT_ARG struct domain *d)
+{
+    XSM_ASSERT_ACTION(XSM_TARGET);
+    return xsm_default_action(action, current->domain, d);
+}
+
+static XSM_INLINE int xsm_map_domain_irq(XSM_DEFAULT_ARG struct domain *d, int 
irq, void *data)
 {
     XSM_ASSERT_ACTION(XSM_HOOK);
     return xsm_default_action(action, current->domain, d);
 }
 
-static XSM_INLINE int xsm_unmap_domain_pirq(XSM_DEFAULT_ARG struct domain *d, 
int irq)
+static XSM_INLINE int xsm_unmap_domain_pirq(XSM_DEFAULT_ARG struct domain *d)
 {
     XSM_ASSERT_ACTION(XSM_TARGET);
     return xsm_default_action(action, current->domain, d);
 }
 
+static XSM_INLINE int xsm_unmap_domain_irq(XSM_DEFAULT_ARG struct domain *d, 
int irq, void *data)
+{
+    XSM_ASSERT_ACTION(XSM_HOOK);
+    return xsm_default_action(action, current->domain, d);
+}
+
 static XSM_INLINE int xsm_irq_permission(XSM_DEFAULT_ARG struct domain *d, int 
pirq, uint8_t allow)
 {
     XSM_ASSERT_ACTION(XSM_HOOK);
diff -r 07d6d8bee6d7 -r 7c6ecf2c1831 xen/include/xsm/xsm.h
--- a/xen/include/xsm/xsm.h     Wed Jan 23 09:17:19 2013 +0000
+++ b/xen/include/xsm/xsm.h     Wed Jan 23 09:18:50 2013 +0000
@@ -101,8 +101,10 @@ struct xsm_operations {
     int (*schedop_shutdown) (struct domain *d1, struct domain *d2);
 
     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 (*map_domain_pirq) (struct domain *d);
+    int (*map_domain_irq) (struct domain *d, int irq, void *data);
+    int (*unmap_domain_pirq) (struct domain *d);
+    int (*unmap_domain_irq) (struct domain *d, int irq, void *data);
     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);
@@ -370,14 +372,24 @@ static inline char *xsm_show_irq_sid (in
     return xsm_ops->show_irq_sid(irq);
 }
 
-static inline int xsm_map_domain_pirq (xsm_default_t def, struct domain *d, 
int irq, void *data)
+static inline int xsm_map_domain_pirq (xsm_default_t def, struct domain *d)
 {
-    return xsm_ops->map_domain_pirq(d, irq, data);
+    return xsm_ops->map_domain_pirq(d);
 }
 
-static inline int xsm_unmap_domain_pirq (xsm_default_t def, struct domain *d, 
int irq)
+static inline int xsm_map_domain_irq (xsm_default_t def, struct domain *d, int 
irq, void *data)
 {
-    return xsm_ops->unmap_domain_pirq(d, irq);
+    return xsm_ops->map_domain_irq(d, irq, data);
+}
+
+static inline int xsm_unmap_domain_pirq (xsm_default_t def, struct domain *d)
+{
+    return xsm_ops->unmap_domain_pirq(d);
+}
+
+static inline int xsm_unmap_domain_irq (xsm_default_t def, struct domain *d, 
int irq, void *data)
+{
+    return xsm_ops->unmap_domain_irq(d, irq, data);
 }
 
 static inline int xsm_irq_permission (xsm_default_t def, struct domain *d, int 
pirq, uint8_t allow)
diff -r 07d6d8bee6d7 -r 7c6ecf2c1831 xen/xsm/dummy.c
--- a/xen/xsm/dummy.c   Wed Jan 23 09:17:19 2013 +0000
+++ b/xen/xsm/dummy.c   Wed Jan 23 09:18:50 2013 +0000
@@ -76,7 +76,9 @@ void xsm_fixup_ops (struct xsm_operation
 
     set_to_dummy_if_null(ops, show_irq_sid);
     set_to_dummy_if_null(ops, map_domain_pirq);
+    set_to_dummy_if_null(ops, map_domain_irq);
     set_to_dummy_if_null(ops, unmap_domain_pirq);
+    set_to_dummy_if_null(ops, unmap_domain_irq);
     set_to_dummy_if_null(ops, irq_permission);
     set_to_dummy_if_null(ops, iomem_permission);
     set_to_dummy_if_null(ops, iomem_mapping);
diff -r 07d6d8bee6d7 -r 7c6ecf2c1831 xen/xsm/flask/hooks.c
--- a/xen/xsm/flask/hooks.c     Wed Jan 23 09:17:19 2013 +0000
+++ b/xen/xsm/flask/hooks.c     Wed Jan 23 09:18:50 2013 +0000
@@ -818,18 +818,18 @@ static char *flask_show_irq_sid (int irq
     return ctx;
 }
 
-static int flask_map_domain_pirq (struct domain *d, int irq, void *data)
+static int flask_map_domain_pirq (struct domain *d)
+{
+    return current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__ADD);
+}
+
+static int flask_map_domain_irq (struct domain *d, int irq, void *data)
 {
     u32 sid, dsid;
     int rc = -EPERM;
     struct msi_info *msi = data;
     struct avc_audit_data ad;
 
-    rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__ADD);
-
-    if ( rc )
-        return rc;
-
     if ( irq >= nr_static_irqs && msi ) {
         u32 machine_bdf = (msi->seg << 16) | (msi->bus << 8) | msi->devfn;
         AVC_AUDIT_DATA_INIT(&ad, DEV);
@@ -851,22 +851,25 @@ static int flask_map_domain_pirq (struct
     return rc;
 }
 
-static int flask_unmap_domain_pirq (struct domain *d, int irq)
+static int flask_unmap_domain_pirq (struct domain *d)
+{
+    return current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__REMOVE);
+}
+
+static int flask_unmap_domain_irq (struct domain *d, int irq, void *data)
 {
     u32 sid;
     int rc = -EPERM;
+    struct msi_info *msi = data;
     struct avc_audit_data ad;
 
-    rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__REMOVE);
-    if ( rc )
-        return rc;
-
-    if ( irq < nr_static_irqs ) {
+    if ( irq >= nr_static_irqs && msi ) {
+        u32 machine_bdf = (msi->seg << 16) | (msi->bus << 8) | msi->devfn;
+        AVC_AUDIT_DATA_INIT(&ad, DEV);
+        ad.device = machine_bdf;
+        rc = security_device_sid(machine_bdf, &sid);
+    } else {
         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;
@@ -1481,7 +1484,9 @@ static struct xsm_operations flask_ops =
     .show_irq_sid = flask_show_irq_sid,
 
     .map_domain_pirq = flask_map_domain_pirq,
+    .map_domain_irq = flask_map_domain_irq,
     .unmap_domain_pirq = flask_unmap_domain_pirq,
+    .unmap_domain_irq = flask_unmap_domain_irq,
     .irq_permission = flask_irq_permission,
     .iomem_permission = flask_iomem_permission,
     .iomem_mapping = flask_iomem_mapping,
diff -r 07d6d8bee6d7 -r 7c6ecf2c1831 xen/xsm/flask/policy/access_vectors
--- a/xen/xsm/flask/policy/access_vectors       Wed Jan 23 09:17:19 2013 +0000
+++ b/xen/xsm/flask/policy/access_vectors       Wed Jan 23 09:18:50 2013 +0000
@@ -368,12 +368,11 @@ class 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
+# PHYSDEVOP_map_pirq and ioapic writes for dom0, when acting on real IRQs
 #  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
+# PHYSDEVOP_unmap_pirq (same as map, and only for real IRQs)
     remove_irq
 # XEN_DOMCTL_ioport_permission, XEN_DOMCTL_ioport_mapping
     add_ioport

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.