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

[Xen-changelog] [xen-unstable] acm: Code restructuring on domain create/destroy.



# 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


 


Rackspace

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