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

[Xen-devel] [Patch][ACM] fix remaining xen handle conversion and fix domain destroy bug -- signed off


  • To: Xen Mailing List <xen-devel@xxxxxxxxxxxxxxxxxxx>
  • From: Reiner Sailer <sailer@xxxxxxxxxx>
  • Date: Thu, 15 Jun 2006 22:15:03 -0400
  • Delivery-date: Thu, 15 Jun 2006 19:15:33 -0700
  • List-id: Xen developer discussion <xen-devel.lists.xensource.com>

This patch completes the conversion of acm_ops using Xen handles instead of void pointers. It also fixes a recently slipped in acm bug that hangs Xen when a domain is destroyed.

Regards
Reiner

Signed-off by: Reiner Sailer <sailer@xxxxxxxxxx>
---
 tools/security/secpol_tool.c |    7 ++++---
 xen/acm/acm_core.c           |    5 ++---
 xen/acm/acm_policy.c         |   41 +++++++++++++++++++++++------------------
 xen/common/acm_ops.c         |    2 +-
 xen/common/dom0_ops.c        |    4 ++--
 xen/include/acm/acm_core.h   |    9 +++++----
 xen/include/acm/acm_hooks.h  |   18 ++++++++++++++++--
 7 files changed, 53 insertions(+), 33 deletions(-)

Index: xen-unstable-test/tools/security/secpol_tool.c
===================================================================
--- xen-unstable-test.orig/tools/security/secpol_tool.c
+++ xen-unstable-test/tools/security/secpol_tool.c
@@ -229,6 +229,7 @@ void acm_dump_policy_buffer(void *buf, i
 
 #define PULL_CACHE_SIZE                8192
 uint8_t pull_buffer[PULL_CACHE_SIZE];
+
 int acm_domain_getpolicy(int xc_handle)
 {
     struct acm_getpolicy getpolicy;
@@ -236,7 +237,7 @@ int acm_domain_getpolicy(int xc_handle)
 
     memset(pull_buffer, 0x00, sizeof(pull_buffer));
     getpolicy.interface_version = ACM_INTERFACE_VERSION;
-    getpolicy.pullcache = (void *) pull_buffer;
+    set_xen_guest_handle(getpolicy.pullcache, pull_buffer);
     getpolicy.pullcache_size = sizeof(pull_buffer);
     ret = xc_acm_op(xc_handle, ACMOP_getpolicy, &getpolicy, sizeof(getpolicy));
 
@@ -281,7 +282,7 @@ int acm_domain_loadpolicy(int xc_handle,
         /* dump it and then push it down into xen/acm */
         acm_dump_policy_buffer(buffer, len);
         setpolicy.interface_version = ACM_INTERFACE_VERSION;
-        setpolicy.pushcache = (void *) buffer;
+        set_xen_guest_handle(setpolicy.pushcache, buffer);
         setpolicy.pushcache_size = len;
         ret = xc_acm_op(xc_handle, ACMOP_setpolicy, &setpolicy, 
sizeof(setpolicy));
 
@@ -330,7 +331,7 @@ int acm_domain_dumpstats(int xc_handle)
 
     memset(stats_buffer, 0x00, sizeof(stats_buffer));
     dumpstats.interface_version = ACM_INTERFACE_VERSION;
-    dumpstats.pullcache = (void *) stats_buffer;
+    set_xen_guest_handle(dumpstats.pullcache, stats_buffer);
     dumpstats.pullcache_size = sizeof(stats_buffer);
     ret = xc_acm_op(xc_handle, ACMOP_dumpstats, &dumpstats, sizeof(dumpstats));
 
Index: xen-unstable-test/xen/acm/acm_core.c
===================================================================
--- xen-unstable-test.orig/xen/acm/acm_core.c
+++ xen-unstable-test/xen/acm/acm_core.c
@@ -222,9 +222,8 @@ acm_setup(unsigned int *initrdidx,
         pol = (struct acm_policy_buffer *)_policy_start;
         if (ntohl(pol->magic) == ACM_MAGIC)
         {
-            rc = acm_set_policy((void *)_policy_start,
-                                (u32)_policy_len,
-                                0);
+            rc = do_acm_set_policy((void *)_policy_start,
+                                   (u32)_policy_len);
             if (rc == ACM_OK)
             {
                 printkd("Policy len  0x%lx, start at 
%p.\n",_policy_len,_policy_start);
Index: xen-unstable-test/xen/acm/acm_policy.c
===================================================================
--- xen-unstable-test.orig/xen/acm/acm_policy.c
+++ xen-unstable-test/xen/acm/acm_policy.c
@@ -26,36 +26,43 @@
 #include <xen/lib.h>
 #include <xen/delay.h>
 #include <xen/sched.h>
+#include <xen/guest_access.h>
 #include <acm/acm_core.h>
 #include <public/acm_ops.h>
 #include <acm/acm_hooks.h>
 #include <acm/acm_endian.h>
 
 int
-acm_set_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size, int isuserbuffer)
+acm_set_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size)
 {
     u8 *policy_buffer = NULL;
-    struct acm_policy_buffer *pol;
+    int ret = -EFAULT;
  
     if (buf_size < sizeof(struct acm_policy_buffer))
         return -EFAULT;
 
-    /* 1. copy buffer from domain */
+    /* copy buffer from guest domain */
     if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL)
         return -ENOMEM;
 
-    if (isuserbuffer) {
-        if (copy_from_guest(policy_buffer, buf, buf_size))
-        {
-            printk("%s: Error copying!\n",__func__);
-            goto error_free;
-        }
-    } else
-        memcpy(policy_buffer, buf, buf_size);
+    if (copy_from_guest(policy_buffer, buf, buf_size))
+    {
+        printk("%s: Error copying!\n",__func__);
+        goto error_free;
+    }
+    ret = do_acm_set_policy(policy_buffer, buf_size);
+
+ error_free:
+    xfree(policy_buffer);
+    return ret;
+}
 
-    /* 2. some sanity checking */
-    pol = (struct acm_policy_buffer *)policy_buffer;
 
+int
+do_acm_set_policy(void *buf, u32 buf_size)
+{
+    struct acm_policy_buffer *pol = (struct acm_policy_buffer *)buf;
+    /* some sanity checking */
     if ((ntohl(pol->magic) != ACM_MAGIC) ||
         (buf_size != ntohl(pol->len)) ||
         (ntohl(pol->policy_version) != ACM_POLICY_VERSION))
@@ -85,33 +92,31 @@ acm_set_policy(XEN_GUEST_HANDLE(void) bu
     /* get bin_policy lock and rewrite policy (release old one) */
     write_lock(&acm_bin_pol_rwlock);
 
-    /* 3. set label reference name */
+    /* set label reference name */
     if (acm_set_policy_reference(buf + ntohl(pol->policy_reference_offset),
                                  ntohl(pol->primary_buffer_offset) -
                                  ntohl(pol->policy_reference_offset)))
         goto error_lock_free;
 
-    /* 4. set primary policy data */
+    /* set primary policy data */
     if (acm_primary_ops->set_binary_policy(buf + 
ntohl(pol->primary_buffer_offset),
                                            ntohl(pol->secondary_buffer_offset) 
-
                                            ntohl(pol->primary_buffer_offset)))
         goto error_lock_free;
 
-    /* 5. set secondary policy data */
+    /* set secondary policy data */
     if (acm_secondary_ops->set_binary_policy(buf + 
ntohl(pol->secondary_buffer_offset),
                                              ntohl(pol->len) - 
                                              
ntohl(pol->secondary_buffer_offset)))
         goto error_lock_free;
 
     write_unlock(&acm_bin_pol_rwlock);
-    xfree(policy_buffer);
     return ACM_OK;
 
  error_lock_free:
     write_unlock(&acm_bin_pol_rwlock);
  error_free:
     printk("%s: Error setting policy.\n", __func__);
-    xfree(policy_buffer);
     return -EFAULT;
 }
 
Index: xen-unstable-test/xen/common/acm_ops.c
===================================================================
--- xen-unstable-test.orig/xen/common/acm_ops.c
+++ xen-unstable-test/xen/common/acm_ops.c
@@ -69,7 +69,7 @@ long do_acm_op(int cmd, XEN_GUEST_HANDLE
             return -EACCES;
 
         rc = acm_set_policy(setpolicy.pushcache,
-                            setpolicy.pushcache_size, 1);
+                            setpolicy.pushcache_size);
         break;
     }
 
Index: xen-unstable-test/xen/common/dom0_ops.c
===================================================================
--- xen-unstable-test.orig/xen/common/dom0_ops.c
+++ xen-unstable-test/xen/common/dom0_ops.c
@@ -701,9 +701,9 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op
     spin_unlock(&dom0_lock);
 
     if (!ret)
-        acm_post_dom0_op(op, ssid);
+        acm_post_dom0_op(op, &ssid);
     else
-        acm_fail_dom0_op(op, ssid);
+        acm_fail_dom0_op(op, &ssid);
 
     return ret;
 }
Index: xen-unstable-test/xen/include/acm/acm_core.h
===================================================================
--- xen-unstable-test.orig/xen/include/acm/acm_core.h
+++ xen-unstable-test/xen/include/acm/acm_core.h
@@ -121,10 +121,11 @@ struct ste_ssid {
 int acm_init_domain_ssid(domid_t id, ssidref_t ssidref);
 void acm_free_domain_ssid(struct acm_ssid_domain *ssid);
 int acm_init_binary_policy(u32 policy_code);
-int acm_set_policy(void *buf, u32 buf_size, int isuserbuffer);
-int acm_get_policy(void *buf, u32 buf_size);
-int acm_dump_statistics(void *buf, u16 buf_size);
-int acm_get_ssid(ssidref_t ssidref, u8 *buf, u16 buf_size);
+int acm_set_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size);
+int do_acm_set_policy(void *buf, u32 buf_size);
+int acm_get_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size);
+int acm_dump_statistics(XEN_GUEST_HANDLE(void) buf, u16 buf_size);
+int acm_get_ssid(ssidref_t ssidref, XEN_GUEST_HANDLE(void) buf, u16 buf_size);
 int acm_get_decision(ssidref_t ssidref1, ssidref_t ssidref2, u32 hook);
 int acm_set_policy_reference(u8 * buf, u32 buf_size);
 int acm_dump_policy_reference(u8 *buf, u32 buf_size);
Index: xen-unstable-test/xen/include/acm/acm_hooks.h
===================================================================
--- xen-unstable-test.orig/xen/include/acm/acm_hooks.h
+++ xen-unstable-test/xen/include/acm/acm_hooks.h
@@ -273,7 +273,12 @@ static inline void acm_post_dom0_op(stru
             op->u.createdomain.domain, op->u.createdomain.ssidref);
         break;
     case DOM0_DESTROYDOMAIN:
-        acm_post_domain_destroy(ssid, op->u.destroydomain.domain);
+        if (*ssid == NULL) {
+            printkd("%s: ERROR. SSID unset.\n",
+                    __func__);
+            break;
+        }
+        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));
         *ssid = NULL;
@@ -281,13 +286,22 @@ static inline void acm_post_dom0_op(stru
     }
 }
 
-static inline void acm_fail_dom0_op(struct dom0_op *op, void *ssid) 
+static inline void acm_fail_dom0_op(struct dom0_op *op, void **ssid)
 {
     switch(op->cmd) {
     case DOM0_CREATEDOMAIN:
         acm_fail_domain_create(
             current->domain->ssid, op->u.createdomain.ssidref);
         break;
+    case DOM0_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;
     }
 }
 
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

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