aboutsummaryrefslogtreecommitdiffstats
path: root/xen/xsm
diff options
context:
space:
mode:
authorDaniel De Graaf <dgdegra@tycho.nsa.gov>2013-01-23 09:18:50 +0000
committerDaniel De Graaf <dgdegra@tycho.nsa.gov>2013-01-23 09:18:50 +0000
commit00b70689c193b9cccb1fac3c3764bed77e152c4e (patch)
tree7407375dc345426e1300ac53bd7ea166996856a8 /xen/xsm
parentdb984809d61b1c605d22520b89fa393bcb21430a (diff)
downloadxen-00b70689c193b9cccb1fac3c3764bed77e152c4e.tar.gz
xen-00b70689c193b9cccb1fac3c3764bed77e152c4e.tar.bz2
xen-00b70689c193b9cccb1fac3c3764bed77e152c4e.zip
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@tycho.nsa.gov> Committed-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/xsm')
-rw-r--r--xen/xsm/dummy.c2
-rw-r--r--xen/xsm/flask/hooks.c37
-rw-r--r--xen/xsm/flask/policy/access_vectors5
3 files changed, 25 insertions, 19 deletions
diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c
index 5031e163a9..dcd3e31526 100644
--- a/xen/xsm/dummy.c
+++ b/xen/xsm/dummy.c
@@ -76,7 +76,9 @@ 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, 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 --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 2a13549045..58695884ae 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -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 domain *d, int irq, void *data)
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 ) {
- rc = get_irq_sid(irq, &sid, &ad);
+ 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 {
- /* 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;
+ rc = get_irq_sid(irq, &sid, &ad);
}
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 --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors
index 2fdaede5e8..36cbacfa13 100644
--- a/xen/xsm/flask/policy/access_vectors
+++ b/xen/xsm/flask/policy/access_vectors
@@ -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