aboutsummaryrefslogtreecommitdiffstats
path: root/xen/xsm
diff options
context:
space:
mode:
authorDaniel De Graaf <dgdegra@tycho.nsa.gov>2011-12-02 13:47:08 -0800
committerDaniel De Graaf <dgdegra@tycho.nsa.gov>2011-12-02 13:47:08 -0800
commit3d7895b3bbe977e3abd2d4128e42c1daba5e3fa4 (patch)
tree3a17a23357b787f377dc3dc669824cc88e352306 /xen/xsm
parent65d744c6d56f92401b9d279c9cf8fe618397be0e (diff)
downloadxen-3d7895b3bbe977e3abd2d4128e42c1daba5e3fa4.tar.gz
xen-3d7895b3bbe977e3abd2d4128e42c1daba5e3fa4.tar.bz2
xen-3d7895b3bbe977e3abd2d4128e42c1daba5e3fa4.zip
xsm: Expand I/O resource hooks
The XSM hooks inside rangeset are not useful in capturing the PIRQ mappings in HVM domains. They can also be called from softirq context where current->domain is invalid, causing spurious AVC denials from unrelated domains on such calls. Within FLASK code, the rangeset hooks were already divided between IRQs, I/O memory, and x86 IO ports; propagate this division back through the XSM hooks and call the XSM functions directly when needed. This removes XSM checks for the initial rangeset population for dom0 and the removal checks on domain destruction; denying either of these actions does not make sense. 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.c14
-rw-r--r--xen/xsm/flask/hooks.c73
2 files changed, 27 insertions, 60 deletions
diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c
index ef461e6ea8..a629396afe 100644
--- a/xen/xsm/dummy.c
+++ b/xen/xsm/dummy.c
@@ -273,13 +273,12 @@ static long dummy___do_xsm_op(XEN_GUEST_HANDLE(xsm_op_t) op)
return -ENOSYS;
}
-static int dummy_add_range (struct domain *d, char *name, unsigned long s, unsigned long e)
+static int dummy_irq_permission (struct domain *d, int pirq, uint8_t allow)
{
return 0;
}
-static int dummy_remove_range (struct domain *d, char *name, unsigned long s,
- unsigned long e)
+static int dummy_iomem_permission (struct domain *d, uint64_t s, uint64_t e, uint8_t allow)
{
return 0;
}
@@ -462,6 +461,10 @@ 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
struct xsm_operations dummy_xsm_ops;
@@ -536,8 +539,8 @@ void xsm_fixup_ops (struct xsm_operations *ops)
set_to_dummy_if_null(ops, kexec);
set_to_dummy_if_null(ops, schedop_shutdown);
- set_to_dummy_if_null(ops, add_range);
- set_to_dummy_if_null(ops, remove_range);
+ set_to_dummy_if_null(ops, irq_permission);
+ set_to_dummy_if_null(ops, iomem_permission);
set_to_dummy_if_null(ops, __do_xsm_op);
@@ -577,5 +580,6 @@ void xsm_fixup_ops (struct xsm_operations *ops)
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);
#endif
}
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 80c1f7017f..1bea49869d 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -643,7 +643,7 @@ static inline u32 resource_to_perm(uint8_t access)
return RESOURCE__REMOVE;
}
-static int irq_has_perm(struct domain *d, uint8_t pirq, uint8_t access)
+static int flask_irq_permission (struct domain *d, int pirq, uint8_t access)
{
u32 perm;
u32 rsid;
@@ -678,10 +678,9 @@ static int irq_has_perm(struct domain *d, uint8_t pirq, uint8_t access)
return rc;
if ( access )
- return avc_has_perm(tsec->sid, rsid, SECCLASS_RESOURCE,
+ rc = avc_has_perm(tsec->sid, rsid, SECCLASS_RESOURCE,
RESOURCE__USE, &ad);
- else
- return rc;
+ return rc;
}
struct iomem_has_perm_data {
@@ -706,7 +705,7 @@ static int _iomem_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 iomem_has_perm(struct domain *d, unsigned long start, unsigned long end, uint8_t access)
+static int flask_iomem_permission(struct domain *d, uint64_t start, uint64_t end, uint8_t access)
{
struct iomem_has_perm_data data;
int rc;
@@ -784,7 +783,7 @@ static int _ioport_has_perm(void *v, u32 sid, unsigned long start, unsigned long
}
-static int ioport_has_perm(struct domain *d, uint32_t start, uint32_t end, uint8_t access)
+static int flask_ioport_permission(struct domain *d, uint32_t start, uint32_t end, uint8_t access)
{
int rc;
struct ioport_has_perm_data data;
@@ -1142,23 +1141,30 @@ static int flask_bind_pt_irq (struct domain *d, struct xen_domctl_bind_pt_irq *b
{
u32 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);
if ( rc )
return rc;
- rc = security_pirq_sid(bind->machine_irq, &rsid);
+ irq = domain_pirq_to_irq(d, bind->machine_irq);
+
+ rc = security_pirq_sid(irq, &rsid);
if ( rc )
return rc;
+ AVC_AUDIT_DATA_INIT(&ad, DEV);
+ ad.device = (unsigned long)irq;
+
ssec = current->domain->ssid;
- rc = avc_has_perm(ssec->sid, rsid, SECCLASS_HVM, HVM__BIND_IRQ, NULL);
+ rc = avc_has_perm(ssec->sid, 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, NULL);
+ return avc_has_perm(tsec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__USE, &ad);
}
static int flask_pin_mem_cacheattr (struct domain *d)
@@ -1205,50 +1211,6 @@ static int flask_vcpuextstate (struct domain *d, uint32_t cmd)
}
#endif
-static int io_has_perm(struct domain *d, char *name, unsigned long s,
- unsigned long e, u32 access)
-{
- int rc = -EPERM;
-
- if ( strcmp(name, "I/O Memory") == 0 )
- {
- rc = iomem_has_perm(d, s, e, access);
- if ( rc )
- return rc;
- }
- else if ( strcmp(name, "Interrupts") == 0 )
- {
- while (s <= e) {
- rc = irq_has_perm(d, s, access);
- if ( rc )
- return rc;
- s++;
- }
- }
-#ifdef CONFIG_X86
- else if ( strcmp(name, "I/O Ports") == 0 )
- {
- rc = ioport_has_perm(d, s, e, access);
- if ( rc )
- return rc;
- }
-#endif
-
- return rc;
-}
-
-static int flask_add_range(struct domain *d, char *name, unsigned long s,
- unsigned long e)
-{
- return io_has_perm(d, name, s, e, 1);
-}
-
-static int flask_remove_range(struct domain *d, char *name, unsigned long s,
- unsigned long e)
-{
- return io_has_perm(d, name, s, e, 0);
-}
-
long do_flask_op(XEN_GUEST_HANDLE(xsm_op_t) u_flask_op);
static struct xsm_operations flask_ops = {
@@ -1308,8 +1270,8 @@ static struct xsm_operations flask_ops = {
.kexec = flask_kexec,
.schedop_shutdown = flask_schedop_shutdown,
- .add_range = flask_add_range,
- .remove_range = flask_remove_range,
+ .irq_permission = flask_irq_permission,
+ .iomem_permission = flask_iomem_permission,
.__do_xsm_op = do_flask_op,
@@ -1348,6 +1310,7 @@ static struct xsm_operations flask_ops = {
.pin_mem_cacheattr = flask_pin_mem_cacheattr,
.ext_vcpucontext = flask_ext_vcpucontext,
.vcpuextstate = flask_vcpuextstate,
+ .ioport_permission = flask_ioport_permission,
#endif
};