WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] This patch

# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 7ba4019f7b2d1db8a5e060b699541dc4b7ccfb8f
# Parent  897adc98fec23d36fd9644a32e608af9ffbbaba5
This patch

* adapts the Xen access control module to recent changes in the "unbound 
event channel" interface and its usage
* adds checks that became necessary because of domain structures "hanging 
around" in the domain list after domain destruction

This patch is tested on today's xen-unstable with Null, CHWALL, STE, 
CHWALL_STE policies.

Signed-off by: Reiner Sailer <sailer@xxxxxxxxxx>

diff -r 897adc98fec2 -r 7ba4019f7b2d xen/acm/acm_simple_type_enforcement_hooks.c
--- a/xen/acm/acm_simple_type_enforcement_hooks.c       Thu Oct 27 16:20:33 2005
+++ b/xen/acm/acm_simple_type_enforcement_hooks.c       Thu Oct 27 16:24:06 2005
@@ -392,8 +392,11 @@
     int i;
 
     printkd("checking cache: %x --> %x.\n", dom->domain_id, rdom);
+
+    if (dom->ssid == NULL)
+        return 0;
     ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
-                         (struct acm_ssid_domain *)(dom)->ssid);
+                         (struct acm_ssid_domain *)(dom->ssid));
 
     for(i=0; i< ACM_TE_CACHE_SIZE; i++) {
         if ((ste_ssid->ste_cache[i].valid == VALID) &&
@@ -412,6 +415,8 @@
     struct ste_ssid *ste_ssid;
     int i;
     printkd("caching from doms: %x --> %x.\n", subj->domain_id, 
obj->domain_id);
+    if (subj->ssid == NULL)
+        return;
     ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
                          (struct acm_ssid_domain *)(subj)->ssid);
     for(i=0; i< ACM_TE_CACHE_SIZE; i++)
@@ -431,26 +436,34 @@
     struct ste_ssid *ste_ssid;
     int i;
     struct domain **pd;
+    struct acm_ssid_domain *ssid;
 
     printkd("deleting cache for dom %x.\n", id);
-
     read_lock(&domlist_lock); /* look through caches of all domains */
     pd = &domain_list;
     for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) {
-        ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
-                             (struct acm_ssid_domain *)(*pd)->ssid);
+        ssid = (struct acm_ssid_domain *)((*pd)->ssid);
+
+        if (ssid == NULL)
+            continue; /* hanging domain structure, no ssid any more ... */
+        ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssid);
+        if (!ste_ssid) {
+            printk("%s: deleting ID from cache ERROR (no ste_ssid)!\n",
+                   __func__);
+            goto out;
+        }
         for (i=0; i<ACM_TE_CACHE_SIZE; i++)
             if ((ste_ssid->ste_cache[i].valid == VALID) &&
-                (ste_ssid->ste_cache[i].id = id))
+                (ste_ssid->ste_cache[i].id == id))
                 ste_ssid->ste_cache[i].valid = FREE;
     }
+ out:
     read_unlock(&domlist_lock);
 }
 
 /***************************
  * Authorization functions
  **************************/
-
 static int 
 ste_pre_domain_create(void *subject_ssid, ssidref_t ssidref)
 {      
@@ -484,19 +497,29 @@
 
 /* -------- EVENTCHANNEL OPERATIONS -----------*/
 static int
-ste_pre_eventchannel_unbound(domid_t id) {
+ste_pre_eventchannel_unbound(domid_t id1, domid_t id2) {
     struct domain *subj, *obj;
     int ret;
-    traceprintk("%s: dom%x-->dom%x.\n", 
-                __func__, current->domain->domain_id, id);
-
-    if (check_cache(current->domain, id)) {
+    traceprintk("%s: dom%x-->dom%x.\n", __func__,
+                (id1 == DOMID_SELF) ? current->domain->domain_id : id1,
+                (id2 == DOMID_SELF) ? current->domain->domain_id : id2);
+
+    if (id1 == DOMID_SELF) id1 = current->domain->domain_id;
+    if (id2 == DOMID_SELF) id2 = current->domain->domain_id;
+
+    subj = find_domain_by_id(id1);
+    obj  = find_domain_by_id(id2);
+    if ((subj == NULL) || (obj == NULL)) {
+        ret = ACM_ACCESS_DENIED;
+        goto out;
+    }
+    /* cache check late */
+    if (check_cache(subj, obj->domain_id)) {
         atomic_inc(&ste_bin_pol.ec_cachehit_count);
-        return ACM_ACCESS_PERMITTED;
+        ret = ACM_ACCESS_PERMITTED;
+        goto out;
     }
     atomic_inc(&ste_bin_pol.ec_eval_count);
-    subj = current->domain;
-    obj = find_domain_by_id(id);
 
     if (share_common_type(subj, obj)) {
         cache_result(subj, obj);
@@ -505,38 +528,43 @@
         atomic_inc(&ste_bin_pol.ec_denied_count); 
         ret = ACM_ACCESS_DENIED; 
     }
+  out:
     if (obj != NULL)
         put_domain(obj);
+    if (subj != NULL)
+        put_domain(subj);
     return ret;
 }
 
 static int
-ste_pre_eventchannel_interdomain(domid_t id1, domid_t id2)
-{
-    struct domain *subj, *obj;
+ste_pre_eventchannel_interdomain(domid_t id)
+{
+    struct domain *subj=NULL, *obj=NULL;
     int ret;
+
     traceprintk("%s: dom%x-->dom%x.\n", __func__,
-                (id1 == DOMID_SELF) ? current->domain->domain_id : id1,
-                (id2 == DOMID_SELF) ? current->domain->domain_id : id2);
+                current->domain->domain_id,
+                (id == DOMID_SELF) ? current->domain->domain_id : id);
 
     /* following is a bit longer but ensures that we
      * "put" only domains that we where "find"-ing 
      */
-    if (id1 == DOMID_SELF) id1 = current->domain->domain_id;
-    if (id2 == DOMID_SELF) id2 = current->domain->domain_id;
-
-    subj = find_domain_by_id(id1);
-    obj  = find_domain_by_id(id2);
-    if ((subj == NULL) || (obj == NULL)) {
+    if (id == DOMID_SELF) id = current->domain->domain_id;
+
+    subj = current->domain;
+    obj  = find_domain_by_id(id);
+    if (obj == NULL) {
         ret = ACM_ACCESS_DENIED;
         goto out;
     }
+
     /* cache check late, but evtchn is not on performance critical path */
     if (check_cache(subj, obj->domain_id)) {
         atomic_inc(&ste_bin_pol.ec_cachehit_count);
         ret = ACM_ACCESS_PERMITTED;
         goto out;
     }
+
     atomic_inc(&ste_bin_pol.ec_eval_count);
 
     if (share_common_type(subj, obj)) {
@@ -549,8 +577,6 @@
  out:
     if (obj != NULL)
         put_domain(obj);
-    if (subj != NULL)
-        put_domain(subj);
     return ret;
 }
 
diff -r 897adc98fec2 -r 7ba4019f7b2d xen/common/acm_ops.c
--- a/xen/common/acm_ops.c      Thu Oct 27 16:20:33 2005
+++ b/xen/common/acm_ops.c      Thu Oct 27 16:24:06 2005
@@ -133,7 +133,10 @@
             struct domain *subj = find_domain_by_id(op->u.getssid.id.domainid);
             if (!subj)
                 return -ESRCH; /* domain not found */
-
+            if (subj->ssid == NULL) {
+                put_domain(subj);
+                return -ESRCH;
+            }
             ssidref = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;
             put_domain(subj);
         } else
@@ -167,6 +170,10 @@
                 ret = -ESRCH; /* domain not found */
                 goto out;
             }
+            if (subj->ssid == NULL) {
+                put_domain(subj);
+                ret = -ESRCH;
+            }
             ssidref1 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;
             put_domain(subj);
         } else {
@@ -181,6 +188,10 @@
             if (!subj) {
                 ret = -ESRCH; /* domain not found */
                 goto out;
+            }
+            if (subj->ssid == NULL) {
+                put_domain(subj);
+                return -ESRCH;
             }
             ssidref2 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;
             put_domain(subj);
diff -r 897adc98fec2 -r 7ba4019f7b2d xen/include/acm/acm_hooks.h
--- a/xen/include/acm/acm_hooks.h       Thu Oct 27 16:20:33 2005
+++ b/xen/include/acm/acm_hooks.h       Thu Oct 27 16:24:06 2005
@@ -100,10 +100,10 @@
     void (*fail_domain_create)         (void *subject_ssid, ssidref_t ssidref);
     void (*post_domain_destroy)        (void *object_ssid, domid_t id);
     /* event channel control hooks  (can be NULL) */
-    int  (*pre_eventchannel_unbound)      (domid_t id);
-    void (*fail_eventchannel_unbound)     (domid_t id);
-    int  (*pre_eventchannel_interdomain)  (domid_t id1, domid_t id2);
-    int  (*fail_eventchannel_interdomain) (domid_t id1, domid_t id2);
+    int  (*pre_eventchannel_unbound)      (domid_t id1, domid_t id2);
+    void (*fail_eventchannel_unbound)     (domid_t id1, domid_t id2);
+    int  (*pre_eventchannel_interdomain)  (domid_t id);
+    void (*fail_eventchannel_interdomain) (domid_t id);
     /* grant table control hooks (can be NULL)  */
     int  (*pre_grant_map_ref)          (domid_t id);
     void (*fail_grant_map_ref)         (domid_t id);
@@ -193,31 +193,31 @@
     return;
 }
 
-static inline int acm_pre_eventchannel_unbound(domid_t id)
+static inline int acm_pre_eventchannel_unbound(domid_t id1, domid_t id2)
 {
     if ((acm_primary_ops->pre_eventchannel_unbound != NULL) && 
-        acm_primary_ops->pre_eventchannel_unbound(id))
+        acm_primary_ops->pre_eventchannel_unbound(id1, id2))
         return ACM_ACCESS_DENIED;
     else if ((acm_secondary_ops->pre_eventchannel_unbound != NULL) && 
-             acm_secondary_ops->pre_eventchannel_unbound(id)) {
+             acm_secondary_ops->pre_eventchannel_unbound(id1, id2)) {
         /* roll-back primary */
         if (acm_primary_ops->fail_eventchannel_unbound != NULL)
-            acm_primary_ops->fail_eventchannel_unbound(id);
+            acm_primary_ops->fail_eventchannel_unbound(id1, id2);
         return ACM_ACCESS_DENIED;
     } else
         return ACM_ACCESS_PERMITTED;
 }
 
-static inline int acm_pre_eventchannel_interdomain(domid_t id1, domid_t id2)
+static inline int acm_pre_eventchannel_interdomain(domid_t id)
 {
     if ((acm_primary_ops->pre_eventchannel_interdomain != NULL) &&
-        acm_primary_ops->pre_eventchannel_interdomain(id1, id2))
+        acm_primary_ops->pre_eventchannel_interdomain(id))
         return ACM_ACCESS_DENIED;
     else if ((acm_secondary_ops->pre_eventchannel_interdomain != NULL) &&
-             acm_secondary_ops->pre_eventchannel_interdomain(id1, id2)) {
+             acm_secondary_ops->pre_eventchannel_interdomain(id)) {
         /* roll-back primary */
         if (acm_primary_ops->fail_eventchannel_interdomain != NULL)
-            acm_primary_ops->fail_eventchannel_interdomain(id1, id2);
+            acm_primary_ops->fail_eventchannel_interdomain(id);
         return ACM_ACCESS_DENIED;
     } else
         return ACM_ACCESS_PERMITTED;
@@ -234,10 +234,22 @@
             current->domain->ssid, op->u.createdomain.ssidref);
         break;
     case DOM0_DESTROYDOMAIN:
+        if (*ssid != NULL) {
+            printkd("%s: Warning. Overlapping destruction.\n", 
+                    __func__);
+            return -EACCES;
+        }
         d = find_domain_by_id(op->u.destroydomain.domain);
         if (d != NULL) {
             *ssid = d->ssid; /* save for post destroy when d is gone */
-            /* no policy-specific hook */
+            if (*ssid == NULL) {
+                printk("%s: Warning. Destroying domain without ssid 
pointer.\n", 
+                       __func__);
+                put_domain(d);
+                return -EACCES;
+            }
+            d->ssid = NULL; /* make sure it's not used any more */
+             /* no policy-specific hook */
             put_domain(d);
             ret = 0;
         }
@@ -248,7 +260,7 @@
     return ret;
 }
 
-static inline void acm_post_dom0_op(dom0_op_t *op, void *ssid) 
+static inline void acm_post_dom0_op(dom0_op_t *op, void **ssid)
 {
     switch(op->cmd) {
     case DOM0_CREATEDOMAIN:
@@ -261,7 +273,8 @@
     case DOM0_DESTROYDOMAIN:
         acm_post_domain_destroy(ssid, op->u.destroydomain.domain);
         /* free security ssid for the destroyed domain (also if null policy */
-        acm_free_domain_ssid((struct acm_ssid_domain *)ssid);
+        acm_free_domain_ssid((struct acm_ssid_domain *)(*ssid));
+        *ssid = NULL;
         break;
     }
 }
@@ -282,12 +295,13 @@
 
     switch(op->cmd) {
     case EVTCHNOP_alloc_unbound:
-        ret = acm_pre_eventchannel_unbound(op->u.alloc_unbound.dom);
+        ret = acm_pre_eventchannel_unbound(
+                  op->u.alloc_unbound.dom,
+                  op->u.alloc_unbound.remote_dom);
         break;
     case EVTCHNOP_bind_interdomain:
         ret = acm_pre_eventchannel_interdomain(
-            current->domain->domain_id,
-            op->u.bind_interdomain.remote_dom);
+                  op->u.bind_interdomain.remote_dom);
         break;
     default:
         ret = 0; /* ok */

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] This patch, Xen patchbot -unstable <=