# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1177429935 -3600
# Node ID a99093e602c6646cb2b4617dd0544ea17edef724
# Parent 4bbc509a0b3fbb1bcf87dcea49ef3558c1d069fa
acm: Code restructuring on domain create/destroy.
When a domain is created, the function acm_domain_create() in
domain_create() is called that does what previously the pre- and
post_domain_create functions were doing. Similarly there's a function
acm_domain_destroy() in domain_kill() that reverts changes to state
when destroying a domain. There's no more separate initialization
necessary for domain-0, but domain_create takes one more parameter,
the ssidref. It is usually passed through the hypercall when a domain
is created.
Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxx>
---
xen/acm/acm_chinesewall_hooks.c | 108 +++++--------
xen/acm/acm_null_hooks.c | 6
xen/acm/acm_simple_type_enforcement_hooks.c | 17 +-
xen/arch/ia64/xen/xensetup.c | 4
xen/arch/powerpc/setup.c | 7
xen/arch/x86/setup.c | 7
xen/common/domain.c | 21 +-
xen/common/domctl.c | 12 -
xen/include/acm/acm_hooks.h | 222 ++++++++--------------------
xen/include/xen/sched.h | 4
10 files changed, 152 insertions(+), 256 deletions(-)
diff -r 4bbc509a0b3f -r a99093e602c6 xen/acm/acm_chinesewall_hooks.c
--- a/xen/acm/acm_chinesewall_hooks.c Tue Apr 24 16:28:37 2007 +0100
+++ b/xen/acm/acm_chinesewall_hooks.c Tue Apr 24 16:52:15 2007 +0100
@@ -407,26 +407,23 @@ static int chwall_dump_ssid_types(ssidre
/* -------- DOMAIN OPERATION HOOKS -----------*/
-static int chwall_pre_domain_create(void *subject_ssid, ssidref_t ssidref)
+static int _chwall_pre_domain_create(void *subject_ssid, ssidref_t ssidref)
{
ssidref_t chwall_ssidref;
int i, j;
traceprintk("%s.\n", __func__);
- read_lock(&acm_bin_pol_rwlock);
chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
if (chwall_ssidref == ACM_DEFAULT_LOCAL_SSID)
{
printk("%s: ERROR CHWALL SSID is NOT SET but policy enforced.\n",
__func__);
- read_unlock(&acm_bin_pol_rwlock);
return ACM_ACCESS_DENIED; /* catching and indicating config
error */
}
if (chwall_ssidref >= chwall_bin_pol.max_ssidrefs)
{
printk("%s: ERROR chwall_ssidref > max(%x).\n",
__func__, chwall_bin_pol.max_ssidrefs - 1);
- read_unlock(&acm_bin_pol_rwlock);
return ACM_ACCESS_DENIED;
}
/* A: chinese wall check for conflicts */
@@ -436,7 +433,6 @@ static int chwall_pre_domain_create(void
chwall_bin_pol.max_types + i])
{
printk("%s: CHINESE WALL CONFLICT in type %02x.\n", __func__, i);
- read_unlock(&acm_bin_pol_rwlock);
return ACM_ACCESS_DENIED;
}
@@ -465,17 +461,16 @@ static int chwall_pre_domain_create(void
chwall_bin_pol.max_types + j])
chwall_bin_pol.conflict_aggregate_set[j]++;
}
- read_unlock(&acm_bin_pol_rwlock);
return ACM_ACCESS_PERMITTED;
}
-static void chwall_post_domain_create(domid_t domid, ssidref_t ssidref)
+
+static void _chwall_post_domain_create(domid_t domid, ssidref_t ssidref)
{
int i, j;
ssidref_t chwall_ssidref;
traceprintk("%s.\n", __func__);
- read_lock(&acm_bin_pol_rwlock);
chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
/* adjust types ref-count for running domains */
for (i = 0; i < chwall_bin_pol.max_types; i++)
@@ -484,7 +479,6 @@ static void chwall_post_domain_create(do
chwall_bin_pol.max_types + i];
if (domid)
{
- read_unlock(&acm_bin_pol_rwlock);
return;
}
/* Xen does not call pre-create hook for DOM0;
@@ -519,19 +513,50 @@ static void chwall_post_domain_create(do
chwall_bin_pol.max_types + j])
chwall_bin_pol.conflict_aggregate_set[j]++;
}
+ return;
+}
+
+
+/*
+ * To be called when creating a domain. If this call is unsuccessful,
+ * no state changes have occurred (adjustments of counters etc.). If it
+ * was successful, state was changed and can be undone using
+ * chwall_domain_destroy.
+ */
+static int chwall_domain_create(void *subject_ssid, ssidref_t ssidref,
+ domid_t domid)
+{
+ int rc;
+ read_lock(&acm_bin_pol_rwlock);
+ rc = _chwall_pre_domain_create(subject_ssid, ssidref);
+ if (rc == ACM_ACCESS_PERMITTED) {
+ _chwall_post_domain_create(domid, ssidref);
+ }
read_unlock(&acm_bin_pol_rwlock);
- return;
-}
-
-static void
-chwall_fail_domain_create(void *subject_ssid, ssidref_t ssidref)
+ return rc;
+}
+
+/*
+ * This function undoes everything a successful call to
+ * chwall_domain_create has done.
+ */
+static void chwall_domain_destroy(void *object_ssid, struct domain *d)
{
int i, j;
- ssidref_t chwall_ssidref;
+ struct chwall_ssid *chwall_ssidp = GET_SSIDP(ACM_CHINESE_WALL_POLICY,
+ (struct acm_ssid_domain *)
+ object_ssid);
+ ssidref_t chwall_ssidref = chwall_ssidp->chwall_ssidref;
+
traceprintk("%s.\n", __func__);
read_lock(&acm_bin_pol_rwlock);
- chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
+ /* adjust running types set */
+ for (i = 0; i < chwall_bin_pol.max_types; i++)
+ chwall_bin_pol.running_types[i] -=
+ chwall_bin_pol.ssidrefs[chwall_ssidref *
+ chwall_bin_pol.max_types + i];
+
/* roll-back: re-adjust conflicting types aggregate */
for (i = 0; i < chwall_bin_pol.max_conflictsets; i++)
{
@@ -557,51 +582,6 @@ chwall_fail_domain_create(void *subject_
chwall_bin_pol.conflict_aggregate_set[j]--;
}
read_unlock(&acm_bin_pol_rwlock);
-}
-
-
-static void chwall_post_domain_destroy(void *object_ssid, domid_t id)
-{
- int i, j;
- struct chwall_ssid *chwall_ssidp = GET_SSIDP(ACM_CHINESE_WALL_POLICY,
- (struct acm_ssid_domain *)
- object_ssid);
- ssidref_t chwall_ssidref = chwall_ssidp->chwall_ssidref;
-
- traceprintk("%s.\n", __func__);
-
- read_lock(&acm_bin_pol_rwlock);
- /* adjust running types set */
- for (i = 0; i < chwall_bin_pol.max_types; i++)
- chwall_bin_pol.running_types[i] -=
- chwall_bin_pol.ssidrefs[chwall_ssidref *
- chwall_bin_pol.max_types + i];
-
- /* roll-back: re-adjust conflicting types aggregate */
- for (i = 0; i < chwall_bin_pol.max_conflictsets; i++)
- {
- int common = 0;
- /* check if conflict_set_i and ssidref have common types */
- for (j = 0; j < chwall_bin_pol.max_types; j++)
- if (chwall_bin_pol.
- conflict_sets[i * chwall_bin_pol.max_types + j]
- && chwall_bin_pol.ssidrefs[chwall_ssidref *
- chwall_bin_pol.max_types + j])
- {
- common = 1;
- break;
- }
- if (common == 0)
- continue; /* try next conflict set, this one does not
include any type of chwall_ssidref */
- /* now add types of the conflict set to conflict_aggregate_set (except
types in chwall_ssidref) */
- for (j = 0; j < chwall_bin_pol.max_types; j++)
- if (chwall_bin_pol.
- conflict_sets[i * chwall_bin_pol.max_types + j]
- && !chwall_bin_pol.ssidrefs[chwall_ssidref *
- chwall_bin_pol.max_types + j])
- chwall_bin_pol.conflict_aggregate_set[j]--;
- }
- read_unlock(&acm_bin_pol_rwlock);
return;
}
@@ -614,10 +594,8 @@ struct acm_operations acm_chinesewall_op
.dump_statistics = chwall_dump_stats,
.dump_ssid_types = chwall_dump_ssid_types,
/* domain management control hooks */
- .pre_domain_create = chwall_pre_domain_create,
- .post_domain_create = chwall_post_domain_create,
- .fail_domain_create = chwall_fail_domain_create,
- .post_domain_destroy = chwall_post_domain_destroy,
+ .domain_create = chwall_domain_create,
+ .domain_destroy = chwall_domain_destroy,
/* event channel control hooks */
.pre_eventchannel_unbound = NULL,
.fail_eventchannel_unbound = NULL,
diff -r 4bbc509a0b3f -r a99093e602c6 xen/acm/acm_null_hooks.c
--- a/xen/acm/acm_null_hooks.c Tue Apr 24 16:28:37 2007 +0100
+++ b/xen/acm/acm_null_hooks.c Tue Apr 24 16:52:15 2007 +0100
@@ -62,10 +62,8 @@ struct acm_operations acm_null_ops = {
.dump_statistics = null_dump_stats,
.dump_ssid_types = null_dump_ssid_types,
/* domain management control hooks */
- .pre_domain_create = NULL,
- .post_domain_create = NULL,
- .fail_domain_create = NULL,
- .post_domain_destroy = NULL,
+ .domain_create = NULL,
+ .domain_destroy = NULL,
/* event channel control hooks */
.pre_eventchannel_unbound = NULL,
.fail_eventchannel_unbound = NULL,
diff -r 4bbc509a0b3f -r a99093e602c6 xen/acm/acm_simple_type_enforcement_hooks.c
--- a/xen/acm/acm_simple_type_enforcement_hooks.c Tue Apr 24 16:28:37
2007 +0100
+++ b/xen/acm/acm_simple_type_enforcement_hooks.c Tue Apr 24 16:52:15
2007 +0100
@@ -500,11 +500,18 @@ ste_pre_domain_create(void *subject_ssid
return ACM_ACCESS_PERMITTED;
}
+static int
+ste_domain_create(void *subject_ssid, ssidref_t ssidref, domid_t domid)
+{
+ return ste_pre_domain_create(subject_ssid, ssidref);
+}
+
+
static void
-ste_post_domain_destroy(void *subject_ssid, domid_t id)
+ste_domain_destroy(void *subject_ssid, struct domain *d)
{
/* clean all cache entries for destroyed domain (might be re-used) */
- clean_id_from_cache(id);
+ clean_id_from_cache(d->domain_id);
}
/* -------- EVENTCHANNEL OPERATIONS -----------*/
@@ -685,10 +692,8 @@ struct acm_operations acm_simple_type_en
.dump_ssid_types = ste_dump_ssid_types,
/* domain management control hooks */
- .pre_domain_create = ste_pre_domain_create,
- .post_domain_create = NULL,
- .fail_domain_create = NULL,
- .post_domain_destroy = ste_post_domain_destroy,
+ .domain_create = ste_domain_create,
+ .domain_destroy = ste_domain_destroy,
/* event channel control hooks */
.pre_eventchannel_unbound = ste_pre_eventchannel_unbound,
diff -r 4bbc509a0b3f -r a99093e602c6 xen/arch/ia64/xen/xensetup.c
--- a/xen/arch/ia64/xen/xensetup.c Tue Apr 24 16:28:37 2007 +0100
+++ b/xen/arch/ia64/xen/xensetup.c Tue Apr 24 16:52:15 2007 +0100
@@ -421,7 +421,7 @@ void start_kernel(void)
scheduler_init();
idle_vcpu[0] = (struct vcpu*) ia64_r13;
- idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
+ idle_domain = domain_create(IDLE_DOMAIN_ID, 0, 0);
if ( (idle_domain == NULL) || (alloc_vcpu(idle_domain, 0, 0) == NULL) )
BUG();
@@ -508,7 +508,7 @@ printk("num_online_cpus=%d, max_cpus=%d\
expose_p2m_init();
/* Create initial domain 0. */
- dom0 = domain_create(0, 0);
+ dom0 = domain_create(0, 0, DOM0_SSIDREF);
if (dom0 == NULL)
panic("Error creating domain 0\n");
dom0_vcpu0 = alloc_vcpu(dom0, 0, 0);
diff -r 4bbc509a0b3f -r a99093e602c6 xen/arch/powerpc/setup.c
--- a/xen/arch/powerpc/setup.c Tue Apr 24 16:28:37 2007 +0100
+++ b/xen/arch/powerpc/setup.c Tue Apr 24 16:52:15 2007 +0100
@@ -162,7 +162,7 @@ static void __init start_of_day(void)
scheduler_init();
/* create idle domain */
- idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
+ idle_domain = domain_create(IDLE_DOMAIN_ID, 0, 0);
if ((idle_domain == NULL) || (alloc_vcpu(idle_domain, 0, 0) == NULL))
BUG();
set_current(idle_domain->vcpu[0]);
@@ -370,7 +370,7 @@ static void __init __start_xen(multiboot
percpu_free_unused_areas();
/* Create initial domain 0. */
- dom0 = domain_create(0, 0);
+ dom0 = domain_create(0, 0, DOM0_SSIDREF);
if (dom0 == NULL)
panic("Error creating domain 0\n");
@@ -379,9 +379,6 @@ static void __init __start_xen(multiboot
dom0->vcpu[0]->cpu_affinity = cpumask_of_cpu(0);
dom0->is_privileged = 1;
-
- /* Post-create hook sets security label. */
- acm_post_domain0_create(dom0->domain_id);
cmdline = (char *)(mod[0].string ? __va((ulong)mod[0].string) : NULL);
diff -r 4bbc509a0b3f -r a99093e602c6 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c Tue Apr 24 16:28:37 2007 +0100
+++ b/xen/arch/x86/setup.c Tue Apr 24 16:52:15 2007 +0100
@@ -254,7 +254,7 @@ static void __init init_idle_domain(void
/* Domain creation requires that scheduler structures are initialised. */
scheduler_init();
- idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
+ idle_domain = domain_create(IDLE_DOMAIN_ID, 0, 0);
if ( (idle_domain == NULL) || (alloc_vcpu(idle_domain, 0, 0) == NULL) )
BUG();
@@ -727,14 +727,11 @@ void __init __start_xen(multiboot_info_t
acm_init(_policy_start, _policy_len);
/* Create initial domain 0. */
- dom0 = domain_create(0, 0);
+ dom0 = domain_create(0, 0, DOM0_SSIDREF);
if ( (dom0 == NULL) || (alloc_vcpu(dom0, 0, 0) == NULL) )
panic("Error creating domain 0\n");
dom0->is_privileged = 1;
-
- /* Post-create hook sets security label. */
- acm_post_domain0_create(dom0->domain_id);
/* Grab the DOM0 command line. */
cmdline = (char *)(mod[0].string ? __va(mod[0].string) : NULL);
diff -r 4bbc509a0b3f -r a99093e602c6 xen/common/domain.c
--- a/xen/common/domain.c Tue Apr 24 16:28:37 2007 +0100
+++ b/xen/common/domain.c Tue Apr 24 16:52:15 2007 +0100
@@ -28,6 +28,7 @@
#include <asm/debugger.h>
#include <public/sched.h>
#include <public/vcpu.h>
+#include <acm/acm_hooks.h>
/* Protect updates/reads (resp.) of domain_list and domain_hash. */
DEFINE_SPINLOCK(domlist_update_lock);
@@ -178,7 +179,7 @@ struct vcpu *alloc_idle_vcpu(unsigned in
return v;
d = (vcpu_id == 0) ?
- domain_create(IDLE_DOMAIN_ID, 0) :
+ domain_create(IDLE_DOMAIN_ID, 0, 0) :
idle_vcpu[cpu_id - vcpu_id]->domain;
BUG_ON(d == NULL);
@@ -188,7 +189,8 @@ struct vcpu *alloc_idle_vcpu(unsigned in
return v;
}
-struct domain *domain_create(domid_t domid, unsigned int domcr_flags)
+struct domain *domain_create(
+ domid_t domid, unsigned int domcr_flags, ssidref_t ssidref)
{
struct domain *d, **pd;
@@ -210,18 +212,21 @@ struct domain *domain_create(domid_t dom
if ( grant_table_create(d) != 0 )
goto fail2;
+
+ if ( acm_domain_create(d, ssidref) != 0 )
+ goto fail3;
}
if ( arch_domain_create(d) != 0 )
- goto fail3;
+ goto fail4;
d->iomem_caps = rangeset_new(d, "I/O Memory", RANGESETF_prettyprint_hex);
d->irq_caps = rangeset_new(d, "Interrupts", 0);
if ( (d->iomem_caps == NULL) || (d->irq_caps == NULL) )
- goto fail4;
+ goto fail5;
if ( sched_init_domain(d) != 0 )
- goto fail4;
+ goto fail5;
if ( !is_idle_domain(d) )
{
@@ -243,8 +248,11 @@ struct domain *domain_create(domid_t dom
return d;
+ fail5:
+ arch_domain_destroy(d);
fail4:
- arch_domain_destroy(d);
+ if ( !is_idle_domain(d) )
+ acm_domain_destroy(d);
fail3:
if ( !is_idle_domain(d) )
grant_table_destroy(d);
@@ -313,6 +321,7 @@ void domain_kill(struct domain *d)
return;
}
+ acm_domain_destroy(d);
gnttab_release_mappings(d);
domain_relinquish_resources(d);
put_domain(d);
diff -r 4bbc509a0b3f -r a99093e602c6 xen/common/domctl.c
--- a/xen/common/domctl.c Tue Apr 24 16:28:37 2007 +0100
+++ b/xen/common/domctl.c Tue Apr 24 16:52:15 2007 +0100
@@ -176,7 +176,6 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
{
long ret = 0;
struct xen_domctl curop, *op = &curop;
- void *ssid = NULL; /* save security ptr between pre and post/fail hooks */
static DEFINE_SPINLOCK(domctl_lock);
if ( !IS_PRIV(current->domain) )
@@ -187,9 +186,6 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( op->interface_version != XEN_DOMCTL_INTERFACE_VERSION )
return -EACCES;
-
- if ( acm_pre_domctl(op, &ssid) )
- return -EPERM;
spin_lock(&domctl_lock);
@@ -334,7 +330,8 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
domcr_flags |= DOMCRF_hvm;
ret = -ENOMEM;
- if ( (d = domain_create(dom, domcr_flags)) == NULL )
+ d = domain_create(dom, domcr_flags, op->u.createdomain.ssidref);
+ if ( d == NULL )
break;
ret = 0;
@@ -716,11 +713,6 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
}
spin_unlock(&domctl_lock);
-
- if ( ret == 0 )
- acm_post_domctl(op, &ssid);
- else
- acm_fail_domctl(op, &ssid);
return ret;
}
diff -r 4bbc509a0b3f -r a99093e602c6 xen/include/acm/acm_hooks.h
--- a/xen/include/acm/acm_hooks.h Tue Apr 24 16:28:37 2007 +0100
+++ b/xen/include/acm/acm_hooks.h Tue Apr 24 16:52:15 2007 +0100
@@ -96,10 +96,9 @@ struct acm_operations {
int (*dump_statistics) (u8 *buffer, u16 buf_size);
int (*dump_ssid_types) (ssidref_t ssidref, u8 *buffer, u16
buf_size);
/* domain management control hooks (can be NULL) */
- int (*pre_domain_create) (void *subject_ssid, ssidref_t ssidref);
- void (*post_domain_create) (domid_t domid, ssidref_t ssidref);
- void (*fail_domain_create) (void *subject_ssid, ssidref_t ssidref);
- void (*post_domain_destroy) (void *object_ssid, domid_t id);
+ int (*domain_create) (void *subject_ssid, ssidref_t ssidref,
+ domid_t domid);
+ void (*domain_destroy) (void *object_ssid, struct domain *d);
/* event channel control hooks (can be NULL) */
int (*pre_eventchannel_unbound) (domid_t id1, domid_t id2);
void (*fail_eventchannel_unbound) (domid_t id1, domid_t id2);
@@ -128,73 +127,32 @@ extern struct acm_operations *acm_second
# define traceprintk(fmt, args...)
#endif
+
#ifndef ACM_SECURITY
-static inline int acm_pre_domctl(struct xen_domctl *op, void **ssid)
-{ return 0; }
-static inline void acm_post_domctl(struct xen_domctl *op, void *ssid)
+static inline int acm_pre_eventchannel_unbound(domid_t id1, domid_t id2)
+{ return 0; }
+static inline int acm_pre_eventchannel_interdomain(domid_t id)
+{ return 0; }
+static inline int acm_pre_grant_map_ref(domid_t id)
+{ return 0; }
+static inline int acm_pre_grant_setup(domid_t id)
+{ return 0; }
+static inline int acm_init(char *policy_start, unsigned long policy_len)
+{ return 0; }
+static inline int acm_is_policy(char *buf, unsigned long len)
+{ return 0; }
+static inline int acm_sharing(ssidref_t ssidref1, ssidref_t ssidref2)
+{ return 0; }
+static inline int acm_domain_create(struct domain *d, ssidref_t ssidref)
+{ return 0; }
+static inline void acm_domain_destroy(struct domain *d)
{ return; }
-static inline void acm_fail_domctl(struct xen_domctl *op, void *ssid)
-{ return; }
-static inline int acm_pre_eventchannel_unbound(domid_t id1, domid_t id2)
-{ return 0; }
-static inline int acm_pre_eventchannel_interdomain(domid_t id)
-{ return 0; }
-static inline int acm_pre_grant_map_ref(domid_t id)
-{ return 0; }
-static inline int acm_pre_grant_setup(domid_t id)
-{ return 0; }
-static inline int acm_init(char *policy_start, unsigned long policy_len)
-{ return 0; }
-static inline int acm_is_policy(char *buf, unsigned long len)
-{ return 0; }
-static inline void acm_post_domain0_create(domid_t domid)
-{ return; }
-static inline int acm_sharing(ssidref_t ssidref1, ssidref_t ssidref2)
-{ return 0; }
+
+#define DOM0_SSIDREF 0x0
#else
-static inline int acm_pre_domain_create(void *subject_ssid, ssidref_t ssidref)
-{
- if ((acm_primary_ops->pre_domain_create != NULL) &&
- acm_primary_ops->pre_domain_create(subject_ssid, ssidref))
- return ACM_ACCESS_DENIED;
- else if ((acm_secondary_ops->pre_domain_create != NULL) &&
- acm_secondary_ops->pre_domain_create(subject_ssid, ssidref)) {
- /* roll-back primary */
- if (acm_primary_ops->fail_domain_create != NULL)
- acm_primary_ops->fail_domain_create(subject_ssid, ssidref);
- return ACM_ACCESS_DENIED;
- } else
- return ACM_ACCESS_PERMITTED;
-}
-
-static inline void acm_post_domain_create(domid_t domid, ssidref_t ssidref)
-{
- if (acm_primary_ops->post_domain_create != NULL)
- acm_primary_ops->post_domain_create(domid, ssidref);
- if (acm_secondary_ops->post_domain_create != NULL)
- acm_secondary_ops->post_domain_create(domid, ssidref);
-}
-
-static inline void acm_fail_domain_create(
- void *subject_ssid, ssidref_t ssidref)
-{
- if (acm_primary_ops->fail_domain_create != NULL)
- acm_primary_ops->fail_domain_create(subject_ssid, ssidref);
- if (acm_secondary_ops->fail_domain_create != NULL)
- acm_secondary_ops->fail_domain_create(subject_ssid, ssidref);
-}
-
-static inline void acm_post_domain_destroy(void *object_ssid, domid_t id)
-{
- if (acm_primary_ops->post_domain_destroy != NULL)
- acm_primary_ops->post_domain_destroy(object_ssid, id);
- if (acm_secondary_ops->post_domain_destroy != NULL)
- acm_secondary_ops->post_domain_destroy(object_ssid, id);
- return;
-}
static inline int acm_pre_eventchannel_unbound(domid_t id1, domid_t id2)
{
@@ -226,85 +184,6 @@ static inline int acm_pre_eventchannel_i
return ACM_ACCESS_PERMITTED;
}
-static inline int acm_pre_domctl(struct xen_domctl *op, void **ssid)
-{
- int ret = -EACCES;
- struct domain *d;
-
- switch(op->cmd) {
- case XEN_DOMCTL_createdomain:
- ret = acm_pre_domain_create(
- current->domain->ssid, op->u.createdomain.ssidref);
- break;
- case XEN_DOMCTL_destroydomain:
- if (*ssid != NULL) {
- printkd("%s: Warning. Overlapping destruction.\n",
- __func__);
- return -EACCES;
- }
- d = rcu_lock_domain_by_id(op->domain);
- if (d != NULL) {
- *ssid = d->ssid; /* save for post destroy when d is gone */
- if (*ssid == NULL) {
- printk("%s: Warning. Destroying domain without ssid
pointer.\n",
- __func__);
- rcu_unlock_domain(d);
- return -EACCES;
- }
- d->ssid = NULL; /* make sure it's not used any more */
- /* no policy-specific hook */
- rcu_unlock_domain(d);
- ret = 0;
- }
- break;
- default:
- ret = 0; /* ok */
- }
- return ret;
-}
-
-static inline void acm_post_domctl(struct xen_domctl *op, void **ssid)
-{
- switch(op->cmd) {
- case XEN_DOMCTL_createdomain:
- /* initialialize shared sHype security labels for new domain */
- acm_init_domain_ssid(
- op->domain, op->u.createdomain.ssidref);
- acm_post_domain_create(
- op->domain, op->u.createdomain.ssidref);
- break;
- case XEN_DOMCTL_destroydomain:
- if (*ssid == NULL) {
- printkd("%s: ERROR. SSID unset.\n",
- __func__);
- break;
- }
- acm_post_domain_destroy(*ssid, op->domain);
- /* free security ssid for the destroyed domain (also if null policy */
- acm_free_domain_ssid((struct acm_ssid_domain *)(*ssid));
- *ssid = NULL;
- break;
- }
-}
-
-static inline void acm_fail_domctl(struct xen_domctl *op, void **ssid)
-{
- switch(op->cmd) {
- case XEN_DOMCTL_createdomain:
- acm_fail_domain_create(
- current->domain->ssid, op->u.createdomain.ssidref);
- break;
- case XEN_DOMCTL_destroydomain:
- /* we don't handle domain destroy failure but at least free the ssid
*/
- if (*ssid == NULL) {
- printkd("%s: ERROR. SSID unset.\n",
- __func__);
- break;
- }
- acm_free_domain_ssid((struct acm_ssid_domain *)(*ssid));
- *ssid = NULL;
- }
-}
static inline int acm_pre_grant_map_ref(domid_t id)
{
@@ -348,14 +227,51 @@ static inline int acm_pre_grant_setup(do
}
}
-static inline void acm_post_domain0_create(domid_t domid)
-{
- /* initialialize shared sHype security labels for new domain */
- int dom0_ssidref = dom0_ste_ssidref << 16 | dom0_chwall_ssidref;
-
- acm_init_domain_ssid(domid, dom0_ssidref);
- acm_post_domain_create(domid, dom0_ssidref);
-}
+
+static inline int acm_domain_create(struct domain *d, ssidref_t ssidref)
+{
+ void *subject_ssid = current->domain->ssid;
+ domid_t domid = d->domain_id;
+ int rc;
+
+ /*
+ To be called when a domain is created; returns '0' if the
+ domain is allowed to be created, != '0' if not.
+ */
+ rc = acm_init_domain_ssid_new(d, ssidref);
+ if (rc != ACM_OK)
+ return rc;
+
+ if ((acm_primary_ops->domain_create != NULL) &&
+ acm_primary_ops->domain_create(subject_ssid, ssidref, domid)) {
+ return ACM_ACCESS_DENIED;
+ } else if ((acm_secondary_ops->domain_create != NULL) &&
+ acm_secondary_ops->domain_create(subject_ssid, ssidref,
+ domid)) {
+ /* roll-back primary */
+ if (acm_primary_ops->domain_destroy != NULL)
+ acm_primary_ops->domain_destroy(d->ssid, d);
+ acm_free_domain_ssid(d->ssid);
+ return ACM_ACCESS_DENIED;
+ }
+
+ return 0;
+}
+
+
+static inline void acm_domain_destroy(struct domain *d)
+{
+ void *ssid = d->ssid;
+ if (ssid != NULL) {
+ if (acm_primary_ops->domain_destroy != NULL)
+ acm_primary_ops->domain_destroy(ssid, d);
+ if (acm_secondary_ops->domain_destroy != NULL)
+ acm_secondary_ops->domain_destroy(ssid, d);
+ /* free security ssid for the destroyed domain (also if null policy */
+ acm_free_domain_ssid((struct acm_ssid_domain *)(ssid));
+ }
+}
+
static inline int acm_sharing(ssidref_t ssidref1, ssidref_t ssidref2)
{
@@ -374,6 +290,8 @@ extern int acm_init(char *policy_start,
/* Return true iff buffer has an acm policy magic number. */
extern int acm_is_policy(char *buf, unsigned long len);
+
+#define DOM0_SSIDREF (dom0_ste_ssidref << 16 | dom0_chwall_ssidref)
#endif
diff -r 4bbc509a0b3f -r a99093e602c6 xen/include/xen/sched.h
--- a/xen/include/xen/sched.h Tue Apr 24 16:28:37 2007 +0100
+++ b/xen/include/xen/sched.h Tue Apr 24 16:52:15 2007 +0100
@@ -10,6 +10,7 @@
#include <public/xen.h>
#include <public/domctl.h>
#include <public/vcpu.h>
+#include <public/acm.h>
#include <xen/time.h>
#include <xen/timer.h>
#include <xen/grant_table.h>
@@ -296,7 +297,8 @@ static inline struct domain *get_current
return d;
}
-struct domain *domain_create(domid_t domid, unsigned int domcr_flags);
+struct domain *domain_create(
+ domid_t domid, unsigned int domcr_flags, ssidref_t ssidref);
/* DOMCRF_hvm: Create an HVM domain, as opposed to a PV domain. */
#define _DOMCRF_hvm 0
#define DOMCRF_hvm (1U<<_DOMCRF_hvm)
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|