direct-io.hg

changeset 10429:21e6625a6c01

[ACM] Complete 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.

Signed-off by: Reiner Sailer <sailer@us.ibm.com>
author kaf24@firebug.cl.cam.ac.uk
date Sat Jun 17 08:38:35 2006 +0100 (2006-06-17)
parents c5a9cf3a998e
children 45f504d6b548
files tools/security/secpol_tool.c xen/acm/acm_core.c xen/acm/acm_policy.c xen/common/acm_ops.c xen/common/dom0_ops.c xen/include/acm/acm_core.h xen/include/acm/acm_hooks.h
line diff
     1.1 --- a/tools/security/secpol_tool.c	Sat Jun 17 08:34:54 2006 +0100
     1.2 +++ b/tools/security/secpol_tool.c	Sat Jun 17 08:38:35 2006 +0100
     1.3 @@ -229,6 +229,7 @@ void acm_dump_policy_buffer(void *buf, i
     1.4  
     1.5  #define PULL_CACHE_SIZE		8192
     1.6  uint8_t pull_buffer[PULL_CACHE_SIZE];
     1.7 +
     1.8  int acm_domain_getpolicy(int xc_handle)
     1.9  {
    1.10      struct acm_getpolicy getpolicy;
    1.11 @@ -236,7 +237,7 @@ int acm_domain_getpolicy(int xc_handle)
    1.12  
    1.13      memset(pull_buffer, 0x00, sizeof(pull_buffer));
    1.14      getpolicy.interface_version = ACM_INTERFACE_VERSION;
    1.15 -    getpolicy.pullcache = (void *) pull_buffer;
    1.16 +    set_xen_guest_handle(getpolicy.pullcache, pull_buffer);
    1.17      getpolicy.pullcache_size = sizeof(pull_buffer);
    1.18      ret = xc_acm_op(xc_handle, ACMOP_getpolicy, &getpolicy, sizeof(getpolicy));
    1.19  
    1.20 @@ -281,7 +282,7 @@ int acm_domain_loadpolicy(int xc_handle,
    1.21          /* dump it and then push it down into xen/acm */
    1.22          acm_dump_policy_buffer(buffer, len);
    1.23          setpolicy.interface_version = ACM_INTERFACE_VERSION;
    1.24 -        setpolicy.pushcache = (void *) buffer;
    1.25 +        set_xen_guest_handle(setpolicy.pushcache, buffer);
    1.26          setpolicy.pushcache_size = len;
    1.27          ret = xc_acm_op(xc_handle, ACMOP_setpolicy, &setpolicy, sizeof(setpolicy));
    1.28  
    1.29 @@ -330,7 +331,7 @@ int acm_domain_dumpstats(int xc_handle)
    1.30  
    1.31      memset(stats_buffer, 0x00, sizeof(stats_buffer));
    1.32      dumpstats.interface_version = ACM_INTERFACE_VERSION;
    1.33 -    dumpstats.pullcache = (void *) stats_buffer;
    1.34 +    set_xen_guest_handle(dumpstats.pullcache, stats_buffer);
    1.35      dumpstats.pullcache_size = sizeof(stats_buffer);
    1.36      ret = xc_acm_op(xc_handle, ACMOP_dumpstats, &dumpstats, sizeof(dumpstats));
    1.37  
     2.1 --- a/xen/acm/acm_core.c	Sat Jun 17 08:34:54 2006 +0100
     2.2 +++ b/xen/acm/acm_core.c	Sat Jun 17 08:38:35 2006 +0100
     2.3 @@ -222,9 +222,8 @@ acm_setup(unsigned int *initrdidx,
     2.4          pol = (struct acm_policy_buffer *)_policy_start;
     2.5          if (ntohl(pol->magic) == ACM_MAGIC)
     2.6          {
     2.7 -            rc = acm_set_policy((void *)_policy_start,
     2.8 -                                (u32)_policy_len,
     2.9 -                                0);
    2.10 +            rc = do_acm_set_policy((void *)_policy_start,
    2.11 +                                   (u32)_policy_len);
    2.12              if (rc == ACM_OK)
    2.13              {
    2.14                  printkd("Policy len  0x%lx, start at %p.\n",_policy_len,_policy_start);
     3.1 --- a/xen/acm/acm_policy.c	Sat Jun 17 08:34:54 2006 +0100
     3.2 +++ b/xen/acm/acm_policy.c	Sat Jun 17 08:38:35 2006 +0100
     3.3 @@ -26,36 +26,43 @@
     3.4  #include <xen/lib.h>
     3.5  #include <xen/delay.h>
     3.6  #include <xen/sched.h>
     3.7 +#include <xen/guest_access.h>
     3.8  #include <acm/acm_core.h>
     3.9  #include <public/acm_ops.h>
    3.10  #include <acm/acm_hooks.h>
    3.11  #include <acm/acm_endian.h>
    3.12  
    3.13  int
    3.14 -acm_set_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size, int isuserbuffer)
    3.15 +acm_set_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size)
    3.16  {
    3.17      u8 *policy_buffer = NULL;
    3.18 -    struct acm_policy_buffer *pol;
    3.19 +    int ret = -EFAULT;
    3.20   
    3.21      if (buf_size < sizeof(struct acm_policy_buffer))
    3.22          return -EFAULT;
    3.23  
    3.24 -    /* 1. copy buffer from domain */
    3.25 +    /* copy buffer from guest domain */
    3.26      if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL)
    3.27          return -ENOMEM;
    3.28  
    3.29 -    if (isuserbuffer) {
    3.30 -        if (copy_from_guest(policy_buffer, buf, buf_size))
    3.31 -        {
    3.32 -            printk("%s: Error copying!\n",__func__);
    3.33 -            goto error_free;
    3.34 -        }
    3.35 -    } else
    3.36 -        memcpy(policy_buffer, buf, buf_size);
    3.37 +    if (copy_from_guest(policy_buffer, buf, buf_size))
    3.38 +    {
    3.39 +        printk("%s: Error copying!\n",__func__);
    3.40 +        goto error_free;
    3.41 +    }
    3.42 +    ret = do_acm_set_policy(policy_buffer, buf_size);
    3.43  
    3.44 -    /* 2. some sanity checking */
    3.45 -    pol = (struct acm_policy_buffer *)policy_buffer;
    3.46 + error_free:
    3.47 +    xfree(policy_buffer);
    3.48 +    return ret;
    3.49 +}
    3.50  
    3.51 +
    3.52 +int
    3.53 +do_acm_set_policy(void *buf, u32 buf_size)
    3.54 +{
    3.55 +    struct acm_policy_buffer *pol = (struct acm_policy_buffer *)buf;
    3.56 +    /* some sanity checking */
    3.57      if ((ntohl(pol->magic) != ACM_MAGIC) ||
    3.58          (buf_size != ntohl(pol->len)) ||
    3.59          (ntohl(pol->policy_version) != ACM_POLICY_VERSION))
    3.60 @@ -85,33 +92,31 @@ acm_set_policy(XEN_GUEST_HANDLE(void) bu
    3.61      /* get bin_policy lock and rewrite policy (release old one) */
    3.62      write_lock(&acm_bin_pol_rwlock);
    3.63  
    3.64 -    /* 3. set label reference name */
    3.65 +    /* set label reference name */
    3.66      if (acm_set_policy_reference(buf + ntohl(pol->policy_reference_offset),
    3.67                                   ntohl(pol->primary_buffer_offset) -
    3.68                                   ntohl(pol->policy_reference_offset)))
    3.69          goto error_lock_free;
    3.70  
    3.71 -    /* 4. set primary policy data */
    3.72 +    /* set primary policy data */
    3.73      if (acm_primary_ops->set_binary_policy(buf + ntohl(pol->primary_buffer_offset),
    3.74                                             ntohl(pol->secondary_buffer_offset) -
    3.75                                             ntohl(pol->primary_buffer_offset)))
    3.76          goto error_lock_free;
    3.77  
    3.78 -    /* 5. set secondary policy data */
    3.79 +    /* set secondary policy data */
    3.80      if (acm_secondary_ops->set_binary_policy(buf + ntohl(pol->secondary_buffer_offset),
    3.81                                               ntohl(pol->len) - 
    3.82                                               ntohl(pol->secondary_buffer_offset)))
    3.83          goto error_lock_free;
    3.84  
    3.85      write_unlock(&acm_bin_pol_rwlock);
    3.86 -    xfree(policy_buffer);
    3.87      return ACM_OK;
    3.88  
    3.89   error_lock_free:
    3.90      write_unlock(&acm_bin_pol_rwlock);
    3.91   error_free:
    3.92      printk("%s: Error setting policy.\n", __func__);
    3.93 -    xfree(policy_buffer);
    3.94      return -EFAULT;
    3.95  }
    3.96  
     4.1 --- a/xen/common/acm_ops.c	Sat Jun 17 08:34:54 2006 +0100
     4.2 +++ b/xen/common/acm_ops.c	Sat Jun 17 08:38:35 2006 +0100
     4.3 @@ -69,7 +69,7 @@ long do_acm_op(int cmd, XEN_GUEST_HANDLE
     4.4              return -EACCES;
     4.5  
     4.6          rc = acm_set_policy(setpolicy.pushcache,
     4.7 -                            setpolicy.pushcache_size, 1);
     4.8 +                            setpolicy.pushcache_size);
     4.9          break;
    4.10      }
    4.11  
     5.1 --- a/xen/common/dom0_ops.c	Sat Jun 17 08:34:54 2006 +0100
     5.2 +++ b/xen/common/dom0_ops.c	Sat Jun 17 08:38:35 2006 +0100
     5.3 @@ -701,9 +701,9 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op
     5.4      spin_unlock(&dom0_lock);
     5.5  
     5.6      if (!ret)
     5.7 -        acm_post_dom0_op(op, ssid);
     5.8 +        acm_post_dom0_op(op, &ssid);
     5.9      else
    5.10 -        acm_fail_dom0_op(op, ssid);
    5.11 +        acm_fail_dom0_op(op, &ssid);
    5.12  
    5.13      return ret;
    5.14  }
     6.1 --- a/xen/include/acm/acm_core.h	Sat Jun 17 08:34:54 2006 +0100
     6.2 +++ b/xen/include/acm/acm_core.h	Sat Jun 17 08:38:35 2006 +0100
     6.3 @@ -121,10 +121,11 @@ struct ste_ssid {
     6.4  int acm_init_domain_ssid(domid_t id, ssidref_t ssidref);
     6.5  void acm_free_domain_ssid(struct acm_ssid_domain *ssid);
     6.6  int acm_init_binary_policy(u32 policy_code);
     6.7 -int acm_set_policy(void *buf, u32 buf_size, int isuserbuffer);
     6.8 -int acm_get_policy(void *buf, u32 buf_size);
     6.9 -int acm_dump_statistics(void *buf, u16 buf_size);
    6.10 -int acm_get_ssid(ssidref_t ssidref, u8 *buf, u16 buf_size);
    6.11 +int acm_set_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size);
    6.12 +int do_acm_set_policy(void *buf, u32 buf_size);
    6.13 +int acm_get_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size);
    6.14 +int acm_dump_statistics(XEN_GUEST_HANDLE(void) buf, u16 buf_size);
    6.15 +int acm_get_ssid(ssidref_t ssidref, XEN_GUEST_HANDLE(void) buf, u16 buf_size);
    6.16  int acm_get_decision(ssidref_t ssidref1, ssidref_t ssidref2, u32 hook);
    6.17  int acm_set_policy_reference(u8 * buf, u32 buf_size);
    6.18  int acm_dump_policy_reference(u8 *buf, u32 buf_size);
     7.1 --- a/xen/include/acm/acm_hooks.h	Sat Jun 17 08:34:54 2006 +0100
     7.2 +++ b/xen/include/acm/acm_hooks.h	Sat Jun 17 08:38:35 2006 +0100
     7.3 @@ -273,7 +273,12 @@ static inline void acm_post_dom0_op(stru
     7.4              op->u.createdomain.domain, op->u.createdomain.ssidref);
     7.5          break;
     7.6      case DOM0_DESTROYDOMAIN:
     7.7 -        acm_post_domain_destroy(ssid, op->u.destroydomain.domain);
     7.8 +        if (*ssid == NULL) {
     7.9 +            printkd("%s: ERROR. SSID unset.\n",
    7.10 +                    __func__);
    7.11 +            break;
    7.12 +        }
    7.13 +        acm_post_domain_destroy(*ssid, op->u.destroydomain.domain);
    7.14          /* free security ssid for the destroyed domain (also if null policy */
    7.15          acm_free_domain_ssid((struct acm_ssid_domain *)(*ssid));
    7.16          *ssid = NULL;
    7.17 @@ -281,13 +286,22 @@ static inline void acm_post_dom0_op(stru
    7.18      }
    7.19  }
    7.20  
    7.21 -static inline void acm_fail_dom0_op(struct dom0_op *op, void *ssid) 
    7.22 +static inline void acm_fail_dom0_op(struct dom0_op *op, void **ssid)
    7.23  {
    7.24      switch(op->cmd) {
    7.25      case DOM0_CREATEDOMAIN:
    7.26          acm_fail_domain_create(
    7.27              current->domain->ssid, op->u.createdomain.ssidref);
    7.28          break;
    7.29 +    case DOM0_DESTROYDOMAIN:
    7.30 +        /*  we don't handle domain destroy failure but at least free the ssid */
    7.31 +        if (*ssid == NULL) {
    7.32 +            printkd("%s: ERROR. SSID unset.\n",
    7.33 +                    __func__);
    7.34 +            break;
    7.35 +        }
    7.36 +        acm_free_domain_ssid((struct acm_ssid_domain *)(*ssid));
    7.37 +        *ssid = NULL;
    7.38      }
    7.39  }
    7.40