ia64/xen-unstable

changeset 16856:cff4c8a1aa28

New XEN_DOMCTL_set_target
Stubdomains (and probably other domain disagregation elements too)
need to be able to tinker with another domain. This adds IS_PRIV_FOR
that extends IS_PRIV by allowing domains to have privileges over a
given "target" domain. XEN_DOMCTL_set_target permits to set this
"target". A new 'target' configuration option makes the domain builder
use it.

Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Jan 23 13:21:44 2008 +0000 (2008-01-23)
parents bcae9d2cc2f8
children 26fc953a89bb
files tools/libxc/xc_domain.c tools/libxc/xenctrl.h tools/python/xen/lowlevel/xc/xc.c tools/python/xen/xend/XendConfig.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xm/create.py xen/arch/ia64/vmx/vmx_hypercall.c xen/arch/ia64/xen/dom0_ops.c xen/arch/ia64/xen/hypercall.c xen/arch/ia64/xen/mm.c xen/arch/ia64/xen/xensetup.c xen/arch/powerpc/setup.c xen/arch/x86/hvm/hvm.c xen/arch/x86/mm.c xen/arch/x86/mm/shadow/multi.c xen/arch/x86/setup.c xen/common/domain.c xen/common/domctl.c xen/common/event_channel.c xen/common/grant_table.c xen/common/memory.c xen/common/schedule.c xen/include/public/domctl.h xen/include/xen/sched.h xen/xsm/acm/acm_simple_type_enforcement_hooks.c
line diff
     1.1 --- a/tools/libxc/xc_domain.c	Wed Jan 23 11:21:35 2008 +0000
     1.2 +++ b/tools/libxc/xc_domain.c	Wed Jan 23 13:21:44 2008 +0000
     1.3 @@ -875,6 +875,20 @@ int xc_domain_ioport_mapping(
     1.4      return do_domctl(xc_handle, &domctl);
     1.5  }
     1.6  
     1.7 +int xc_domain_set_target(
     1.8 +    int xc_handle,
     1.9 +    uint32_t domid,
    1.10 +    uint32_t target)
    1.11 +{
    1.12 +    DECLARE_DOMCTL;
    1.13 +
    1.14 +    domctl.cmd = XEN_DOMCTL_set_target;
    1.15 +    domctl.domain = domid;
    1.16 +    domctl.u.set_target.target = target;
    1.17 +
    1.18 +    return do_domctl(xc_handle, &domctl);
    1.19 +}
    1.20 +
    1.21  /*
    1.22   * Local variables:
    1.23   * mode: C
     2.1 --- a/tools/libxc/xenctrl.h	Wed Jan 23 11:21:35 2008 +0000
     2.2 +++ b/tools/libxc/xenctrl.h	Wed Jan 23 13:21:44 2008 +0000
     2.3 @@ -952,4 +952,9 @@ int xc_domain_bind_pt_isa_irq(int xc_han
     2.4                                uint32_t domid,
     2.5                                uint8_t machine_irq);
     2.6  
     2.7 +/* Set the target domain */
     2.8 +int xc_domain_set_target(int xc_handle,
     2.9 +                         uint32_t domid,
    2.10 +                         uint32_t target);
    2.11 +
    2.12  #endif /* XENCTRL_H */
     3.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Wed Jan 23 11:21:35 2008 +0000
     3.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Wed Jan 23 13:21:44 2008 +0000
     3.3 @@ -96,17 +96,17 @@ static PyObject *pyxc_domain_create(XcOb
     3.4                                      PyObject *args,
     3.5                                      PyObject *kwds)
     3.6  {
     3.7 -    uint32_t dom = 0, ssidref = 0, flags = 0;
     3.8 +    uint32_t dom = 0, ssidref = 0, flags = 0, target = 0;
     3.9      int      ret, i, hvm = 0;
    3.10      PyObject *pyhandle = NULL;
    3.11      xen_domain_handle_t handle = { 
    3.12          0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
    3.13          0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef };
    3.14  
    3.15 -    static char *kwd_list[] = { "domid", "ssidref", "handle", "hvm", NULL };
    3.16 +    static char *kwd_list[] = { "domid", "ssidref", "handle", "hvm", "target", NULL };
    3.17  
    3.18 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiOi", kwd_list,
    3.19 -                                      &dom, &ssidref, &pyhandle, &hvm))
    3.20 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiOii", kwd_list,
    3.21 +				      &dom, &ssidref, &pyhandle, &hvm, &target))
    3.22          return NULL;
    3.23  
    3.24      if ( pyhandle != NULL )
    3.25 @@ -131,6 +131,11 @@ static PyObject *pyxc_domain_create(XcOb
    3.26                                   handle, flags, &dom)) < 0 )
    3.27          return pyxc_error_to_exception();
    3.28  
    3.29 +    if ( target )
    3.30 +        if ( (ret = xc_domain_set_target(self->xc_handle, dom, target)) < 0 )
    3.31 +            return pyxc_error_to_exception();
    3.32 +
    3.33 +
    3.34      return PyInt_FromLong(dom);
    3.35  
    3.36  out_exception:
     4.1 --- a/tools/python/xen/xend/XendConfig.py	Wed Jan 23 11:21:35 2008 +0000
     4.2 +++ b/tools/python/xen/xend/XendConfig.py	Wed Jan 23 13:21:44 2008 +0000
     4.3 @@ -170,6 +170,7 @@ XENAPI_CFG_TYPES = {
     4.4      'platform': dict,
     4.5      'tools_version': dict,
     4.6      'other_config': dict,
     4.7 +    'target': int,
     4.8      'security_label': str,
     4.9      'pci': str,
    4.10  }
    4.11 @@ -336,7 +337,8 @@ class XendConfig(dict):
    4.12              'vbd_refs': [],
    4.13              'vtpm_refs': [],
    4.14              'other_config': {},
    4.15 -            'platform': {}
    4.16 +            'platform': {},
    4.17 +            'target': 0,
    4.18          }
    4.19          
    4.20          return defaults
    4.21 @@ -1585,6 +1587,9 @@ class XendConfig(dict):
    4.22      def is_hvm(self):
    4.23          return self['HVM_boot_policy'] != ''
    4.24  
    4.25 +    def target(self):
    4.26 +	return self['target']
    4.27 +
    4.28      def image_type(self):
    4.29          stored_type = self['platform'].get('image_type')
    4.30          return stored_type or (self.is_hvm() and 'hvm' or 'linux')
     5.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Wed Jan 23 11:21:35 2008 +0000
     5.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Wed Jan 23 13:21:44 2008 +0000
     5.3 @@ -1640,7 +1640,8 @@ class XendDomainInfo:
     5.4                  domid = 0,
     5.5                  ssidref = ssidref,
     5.6                  handle = uuid.fromString(self.info['uuid']),
     5.7 -                hvm = int(hvm))
     5.8 +                hvm = int(hvm),
     5.9 +                target = self.info.target())
    5.10          except Exception, e:
    5.11              # may get here if due to ACM the operation is not permitted
    5.12              if security.on():
     6.1 --- a/tools/python/xen/xm/create.py	Wed Jan 23 11:21:35 2008 +0000
     6.2 +++ b/tools/python/xen/xm/create.py	Wed Jan 23 13:21:44 2008 +0000
     6.3 @@ -521,6 +521,10 @@ gopts.var('on_xend_stop', val='ignore|sh
     6.4            - suspend:        Domain is suspended;
     6.5            """)
     6.6  
     6.7 +gopts.var('target', val='TARGET',
     6.8 +          fn=set_int, default=0,
     6.9 +          use="Set domain target.")
    6.10 +
    6.11  def err(msg):
    6.12      """Print an error to stderr and exit.
    6.13      """
    6.14 @@ -748,7 +752,7 @@ def make_config(vals):
    6.15      map(add_conf, ['name', 'memory', 'maxmem', 'shadow_memory',
    6.16                     'restart', 'on_poweroff',
    6.17                     'on_reboot', 'on_crash', 'vcpus', 'vcpu_avail', 'features',
    6.18 -                   'on_xend_start', 'on_xend_stop'])
    6.19 +                   'on_xend_start', 'on_xend_stop', 'target'])
    6.20  
    6.21      if vals.uuid is not None:
    6.22          config.append(['uuid', vals.uuid])
     7.1 --- a/xen/arch/ia64/vmx/vmx_hypercall.c	Wed Jan 23 11:21:35 2008 +0000
     7.2 +++ b/xen/arch/ia64/vmx/vmx_hypercall.c	Wed Jan 23 13:21:44 2008 +0000
     7.3 @@ -47,9 +47,6 @@ static int hvmop_set_isa_irq_level(
     7.4      if ( copy_from_guest(&op, uop, 1) )
     7.5          return -EFAULT;
     7.6  
     7.7 -    if ( !IS_PRIV(current->domain) )
     7.8 -        return -EPERM;
     7.9 -
    7.10      if ( op.isa_irq > 15 )
    7.11          return -EINVAL;
    7.12  
    7.13 @@ -57,6 +54,10 @@ static int hvmop_set_isa_irq_level(
    7.14      if ( d == NULL )
    7.15          return -ESRCH;
    7.16  
    7.17 +    rc = -EPERM;
    7.18 +    if ( !IS_PRIV_FOR(current->domain, d) )
    7.19 +        goto out;
    7.20 +
    7.21      rc = -EINVAL;
    7.22      if ( !is_hvm_domain(d) )
    7.23          goto out;
    7.24 @@ -79,9 +80,6 @@ static int hvmop_set_pci_intx_level(
    7.25      if ( copy_from_guest(&op, uop, 1) )
    7.26          return -EFAULT;
    7.27  
    7.28 -    if ( !IS_PRIV(current->domain) )
    7.29 -        return -EPERM;
    7.30 -
    7.31      if ( (op.domain > 0) || (op.bus > 0) || (op.device > 31) || (op.intx > 3) )
    7.32          return -EINVAL;
    7.33  
    7.34 @@ -89,6 +87,10 @@ static int hvmop_set_pci_intx_level(
    7.35      if ( d == NULL )
    7.36          return -ESRCH;
    7.37  
    7.38 +    rc = -EPERM;
    7.39 +    if ( !IS_PRIV_FOR(current->domain, d) )
    7.40 +        goto out;
    7.41 +
    7.42      rc = -EINVAL;
    7.43      if ( !is_hvm_domain(d) )
    7.44          goto out;
    7.45 @@ -124,13 +126,15 @@ do_hvm_op(unsigned long op, XEN_GUEST_HA
    7.46          if (a.domid == DOMID_SELF) {
    7.47              d = rcu_lock_current_domain();
    7.48          }
    7.49 -        else if (IS_PRIV(current->domain)) {
    7.50 +        else {
    7.51              d = rcu_lock_domain_by_id(a.domid);
    7.52              if (d == NULL)
    7.53                  return -ESRCH;
    7.54 +            if (!IS_PRIV_FOR(current->domain, d)) {
    7.55 +                rcu_unlock_domain(d);
    7.56 +                return -EPERM;
    7.57 +            }
    7.58          }
    7.59 -        else
    7.60 -            return -EPERM;
    7.61  
    7.62          if (op == HVMOP_set_param) {
    7.63              struct vmx_ioreq_page *iorp;
     8.1 --- a/xen/arch/ia64/xen/dom0_ops.c	Wed Jan 23 11:21:35 2008 +0000
     8.2 +++ b/xen/arch/ia64/xen/dom0_ops.c	Wed Jan 23 13:21:44 2008 +0000
     8.3 @@ -37,9 +37,6 @@ long arch_do_domctl(xen_domctl_t *op, XE
     8.4  {
     8.5      long ret = 0;
     8.6  
     8.7 -    if ( !IS_PRIV(current->domain) )
     8.8 -        return -EPERM;
     8.9 -
    8.10      switch ( op->cmd )
    8.11      {
    8.12      case XEN_DOMCTL_getmemlist:
    8.13 @@ -54,6 +51,13 @@ long arch_do_domctl(xen_domctl_t *op, XE
    8.14              ret = -EINVAL;
    8.15              break;
    8.16          }
    8.17 +
    8.18 +        if ( !IS_PRIV_FOR(current->domain, d) ) {
    8.19 +            ret = -EPERM;
    8.20 +            rcu_unlock_domain(d);
    8.21 +            break;
    8.22 +        }
    8.23 +
    8.24          for (i = 0 ; i < nr_pages ; i++) {
    8.25              pte_t *pte;
    8.26  
    8.27 @@ -87,6 +91,12 @@ long arch_do_domctl(xen_domctl_t *op, XE
    8.28              break;
    8.29          }
    8.30  
    8.31 +        if ( !IS_PRIV_FOR(current->domain, d) ) {
    8.32 +            ret = -EPERM;
    8.33 +            rcu_unlock_domain(d);
    8.34 +            break;
    8.35 +        }
    8.36 +
    8.37          if (ds->flags & XEN_DOMAINSETUP_query) {
    8.38              /* Set flags.  */
    8.39              if (is_hvm_domain(d))
    8.40 @@ -153,6 +163,12 @@ long arch_do_domctl(xen_domctl_t *op, XE
    8.41          d = rcu_lock_domain_by_id(op->domain);
    8.42          if ( d != NULL )
    8.43          {
    8.44 +            if ( !IS_PRIV_FOR(current->domain, d) ) {
    8.45 +                ret = -EPERM;
    8.46 +                rcu_unlock_domain(d);
    8.47 +                break;
    8.48 +            }
    8.49 +
    8.50              ret = shadow_mode_control(d, &op->u.shadow_op);
    8.51              rcu_unlock_domain(d);
    8.52              if (copy_to_guest(u_domctl, op, 1))
    8.53 @@ -173,6 +189,12 @@ long arch_do_domctl(xen_domctl_t *op, XE
    8.54          if (unlikely(d == NULL))
    8.55              break;
    8.56  
    8.57 +        if ( !IS_PRIV_FOR(current->domain, d) ) {
    8.58 +            ret = -EPERM;
    8.59 +            rcu_unlock_domain(d);
    8.60 +            break;
    8.61 +        }
    8.62 +
    8.63          if (np == 0)
    8.64              ret = 0;
    8.65          else {
    8.66 @@ -196,6 +218,11 @@ long arch_do_domctl(xen_domctl_t *op, XE
    8.67          if ( d == NULL )
    8.68              break;
    8.69  
    8.70 +        ret = -EPERM;
    8.71 +        if ( !IS_PRIV_FOR(current->domain, d) ) {
    8.72 +            goto sendtrigger_out;
    8.73 +        }
    8.74 +
    8.75          ret = -EINVAL;
    8.76          if ( op->u.sendtrigger.vcpu >= MAX_VIRT_CPUS )
    8.77              goto sendtrigger_out;
    8.78 @@ -239,6 +266,10 @@ long arch_do_domctl(xen_domctl_t *op, XE
    8.79          if (d == NULL)
    8.80              break;
    8.81  
    8.82 +        ret = -EPERM;
    8.83 +        if ( !IS_PRIV_FOR(current->domain, d) )
    8.84 +            goto sethvmcontext_out;
    8.85 +
    8.86  #ifdef CONFIG_X86
    8.87          ret = xsm_hvmcontext(d, op->cmd);
    8.88          if (ret)
    8.89 @@ -280,6 +311,10 @@ long arch_do_domctl(xen_domctl_t *op, XE
    8.90          if (d == NULL)
    8.91              break;
    8.92  
    8.93 +        ret = -EPERM;
    8.94 +        if ( !IS_PRIV_FOR(current->domain, d) )
    8.95 +            goto gethvmcontext_out;
    8.96 +
    8.97  #ifdef CONFIG_X86
    8.98          ret = xsm_hvmcontext(d, op->cmd);
    8.99          if (ret)
   8.100 @@ -341,7 +376,10 @@ long arch_do_domctl(xen_domctl_t *op, XE
   8.101              break;
   8.102          }
   8.103  
   8.104 -        ret = domain_opt_feature(d, optf);
   8.105 +        ret = -EPERM;
   8.106 +        if ( IS_PRIV_FOR(current->domain, d) )
   8.107 +            ret = domain_opt_feature(d, optf);
   8.108 +
   8.109          rcu_unlock_domain(d);
   8.110      }
   8.111      break;
     9.1 --- a/xen/arch/ia64/xen/hypercall.c	Wed Jan 23 11:21:35 2008 +0000
     9.2 +++ b/xen/arch/ia64/xen/hypercall.c	Wed Jan 23 13:21:44 2008 +0000
     9.3 @@ -500,13 +500,15 @@ do_ia64_debug_op(unsigned long cmd, unsi
     9.4      struct domain *d;
     9.5      long ret = 0;
     9.6  
     9.7 -    if (!IS_PRIV(current->domain))
     9.8 -        return -EPERM;
     9.9      if (copy_from_guest(op, u_debug_op, 1))
    9.10          return -EFAULT;
    9.11      d = rcu_lock_domain_by_id(domain);
    9.12      if (d == NULL)
    9.13          return -ESRCH;
    9.14 +    if (!IS_PRIV_FOR(current->domain, d)) {
    9.15 +        ret = -EPERM;
    9.16 +        goto out;
    9.17 +    }
    9.18  
    9.19      switch (cmd) {
    9.20      case XEN_IA64_DEBUG_OP_SET_FLAGS:
    9.21 @@ -520,6 +522,7 @@ do_ia64_debug_op(unsigned long cmd, unsi
    9.22      default:
    9.23          ret = -ENOSYS;
    9.24      }
    9.25 +out:
    9.26      rcu_unlock_domain(d);
    9.27      return ret;
    9.28  }
    10.1 --- a/xen/arch/ia64/xen/mm.c	Wed Jan 23 11:21:35 2008 +0000
    10.2 +++ b/xen/arch/ia64/xen/mm.c	Wed Jan 23 13:21:44 2008 +0000
    10.3 @@ -2787,10 +2787,14 @@ arch_memory_op(int op, XEN_GUEST_HANDLE(
    10.4  
    10.5          if (xatp.domid == DOMID_SELF)
    10.6              d = rcu_lock_current_domain();
    10.7 -        else if (!IS_PRIV(current->domain))
    10.8 -            return -EPERM;
    10.9 -        else if ((d = rcu_lock_domain_by_id(xatp.domid)) == NULL)
   10.10 -            return -ESRCH;
   10.11 +        else {
   10.12 +            if ((d = rcu_lock_domain_by_id(xatp.domid)) == NULL)
   10.13 +                return -ESRCH;
   10.14 +            if (!IS_PRIV_FOR(current->domain,d)) {
   10.15 +                rcu_lock_domain(d);
   10.16 +                return -EPERM;
   10.17 +            }
   10.18 +        }
   10.19  
   10.20          /* This hypercall is used for VT-i domain only */
   10.21          if (!VMX_DOMAIN(d->vcpu[0])) {
    11.1 --- a/xen/arch/ia64/xen/xensetup.c	Wed Jan 23 11:21:35 2008 +0000
    11.2 +++ b/xen/arch/ia64/xen/xensetup.c	Wed Jan 23 13:21:44 2008 +0000
    11.3 @@ -642,6 +642,7 @@ printk("num_online_cpus=%d, max_cpus=%d\
    11.4          panic("Cannot allocate dom0 vcpu 0\n");
    11.5  
    11.6      dom0->is_privileged = 1;
    11.7 +    dom0->target = NULL;
    11.8  
    11.9      /*
   11.10       * We're going to setup domain0 using the module(s) that we stashed safely
    12.1 --- a/xen/arch/powerpc/setup.c	Wed Jan 23 11:21:35 2008 +0000
    12.2 +++ b/xen/arch/powerpc/setup.c	Wed Jan 23 13:21:44 2008 +0000
    12.3 @@ -375,6 +375,7 @@ static void __init __start_xen(void)
    12.4      dom0->vcpu[0]->cpu_affinity = cpumask_of_cpu(0);
    12.5  
    12.6      dom0->is_privileged = 1;
    12.7 +    dom0->target = NULL;
    12.8  
    12.9      /* scrub_heap_pages() requires IRQs enabled, and we're post IRQ setup... */
   12.10      local_irq_enable();
    13.1 --- a/xen/arch/x86/hvm/hvm.c	Wed Jan 23 11:21:35 2008 +0000
    13.2 +++ b/xen/arch/x86/hvm/hvm.c	Wed Jan 23 13:21:44 2008 +0000
    13.3 @@ -1740,9 +1740,6 @@ static int hvmop_set_pci_intx_level(
    13.4      if ( copy_from_guest(&op, uop, 1) )
    13.5          return -EFAULT;
    13.6  
    13.7 -    if ( !IS_PRIV(current->domain) )
    13.8 -        return -EPERM;
    13.9 -
   13.10      if ( (op.domain > 0) || (op.bus > 0) || (op.device > 31) || (op.intx > 3) )
   13.11          return -EINVAL;
   13.12  
   13.13 @@ -1750,6 +1747,10 @@ static int hvmop_set_pci_intx_level(
   13.14      if ( d == NULL )
   13.15          return -ESRCH;
   13.16  
   13.17 +    rc = -EPERM;
   13.18 +    if ( !IS_PRIV_FOR(current->domain, d) )
   13.19 +        goto out;
   13.20 +
   13.21      rc = -EINVAL;
   13.22      if ( !is_hvm_domain(d) )
   13.23          goto out;
   13.24 @@ -1787,9 +1788,6 @@ static int hvmop_set_isa_irq_level(
   13.25      if ( copy_from_guest(&op, uop, 1) )
   13.26          return -EFAULT;
   13.27  
   13.28 -    if ( !IS_PRIV(current->domain) )
   13.29 -        return -EPERM;
   13.30 -
   13.31      if ( op.isa_irq > 15 )
   13.32          return -EINVAL;
   13.33  
   13.34 @@ -1797,6 +1795,10 @@ static int hvmop_set_isa_irq_level(
   13.35      if ( d == NULL )
   13.36          return -ESRCH;
   13.37  
   13.38 +    rc = -EPERM;
   13.39 +    if ( !IS_PRIV_FOR(current->domain, d) )
   13.40 +        goto out;
   13.41 +
   13.42      rc = -EINVAL;
   13.43      if ( !is_hvm_domain(d) )
   13.44          goto out;
   13.45 @@ -1834,9 +1836,6 @@ static int hvmop_set_pci_link_route(
   13.46      if ( copy_from_guest(&op, uop, 1) )
   13.47          return -EFAULT;
   13.48  
   13.49 -    if ( !IS_PRIV(current->domain) )
   13.50 -        return -EPERM;
   13.51 -
   13.52      if ( (op.link > 3) || (op.isa_irq > 15) )
   13.53          return -EINVAL;
   13.54  
   13.55 @@ -1844,6 +1843,10 @@ static int hvmop_set_pci_link_route(
   13.56      if ( d == NULL )
   13.57          return -ESRCH;
   13.58  
   13.59 +    rc = -EPERM;
   13.60 +    if ( !IS_PRIV_FOR(current->domain, d) )
   13.61 +        goto out;
   13.62 +
   13.63      rc = -EINVAL;
   13.64      if ( !is_hvm_domain(d) )
   13.65          goto out;
   13.66 @@ -1921,13 +1924,16 @@ long do_hvm_op(unsigned long op, XEN_GUE
   13.67  
   13.68          if ( a.domid == DOMID_SELF )
   13.69              d = rcu_lock_current_domain();
   13.70 -        else if ( IS_PRIV(current->domain) )
   13.71 +        else {
   13.72              d = rcu_lock_domain_by_id(a.domid);
   13.73 -        else
   13.74 -            return -EPERM;
   13.75 +            if ( d == NULL )
   13.76 +                return -ESRCH;
   13.77 +            if ( !IS_PRIV_FOR(current->domain, d) ) {
   13.78 +                rc = -EPERM;
   13.79 +                goto param_fail;
   13.80 +            }
   13.81 +        }
   13.82  
   13.83 -        if ( d == NULL )
   13.84 -            return -ESRCH;
   13.85  
   13.86          rc = -EINVAL;
   13.87          if ( !is_hvm_domain(d) )
    14.1 --- a/xen/arch/x86/mm.c	Wed Jan 23 11:21:35 2008 +0000
    14.2 +++ b/xen/arch/x86/mm.c	Wed Jan 23 13:21:44 2008 +0000
    14.3 @@ -2056,38 +2056,35 @@ static int set_foreigndom(domid_t domid)
    14.4          MEM_LOG("Cannot mix foreign mappings with translated domains");
    14.5          okay = 0;
    14.6      }
    14.7 -    else if ( !IS_PRIV(d) )
    14.8 +    else switch ( domid )
    14.9      {
   14.10 -        switch ( domid )
   14.11 -        {
   14.12 -        case DOMID_IO:
   14.13 -            info->foreign = rcu_lock_domain(dom_io);
   14.14 -            break;
   14.15 -        default:
   14.16 +    case DOMID_IO:
   14.17 +        info->foreign = rcu_lock_domain(dom_io);
   14.18 +        break;
   14.19 +    case DOMID_XEN:
   14.20 +        if (!IS_PRIV(d)) {
   14.21              MEM_LOG("Cannot set foreign dom");
   14.22              okay = 0;
   14.23              break;
   14.24          }
   14.25 -    }
   14.26 -    else
   14.27 -    {
   14.28 -        info->foreign = e = rcu_lock_domain_by_id(domid);
   14.29 +        info->foreign = rcu_lock_domain(dom_xen);
   14.30 +        break;
   14.31 +    default:
   14.32 +        e = rcu_lock_domain_by_id(domid);
   14.33          if ( e == NULL )
   14.34          {
   14.35 -            switch ( domid )
   14.36 -            {
   14.37 -            case DOMID_XEN:
   14.38 -                info->foreign = rcu_lock_domain(dom_xen);
   14.39 -                break;
   14.40 -            case DOMID_IO:
   14.41 -                info->foreign = rcu_lock_domain(dom_io);
   14.42 -                break;
   14.43 -            default:
   14.44 -                MEM_LOG("Unknown domain '%u'", domid);
   14.45 -                okay = 0;
   14.46 -                break;
   14.47 -            }
   14.48 +            MEM_LOG("Unknown domain '%u'", domid);
   14.49 +            okay = 0;
   14.50 +            break;
   14.51          }
   14.52 +        if (!IS_PRIV_FOR(d, e)) {
   14.53 +            MEM_LOG("Cannot set foreign dom");
   14.54 +            okay = 0;
   14.55 +            rcu_unlock_domain(e);
   14.56 +            break;
   14.57 +        }
   14.58 +        info->foreign = e;
   14.59 +        break;
   14.60      }
   14.61  
   14.62   out:
   14.63 @@ -3043,9 +3040,6 @@ int do_update_va_mapping_otherdomain(uns
   14.64  {
   14.65      int rc;
   14.66  
   14.67 -    if ( unlikely(!IS_PRIV(current->domain)) )
   14.68 -        return -EPERM;
   14.69 -
   14.70      if ( !set_foreigndom(domid) )
   14.71          return -ESRCH;
   14.72  
   14.73 @@ -3222,10 +3216,15 @@ long arch_memory_op(int op, XEN_GUEST_HA
   14.74  
   14.75          if ( xatp.domid == DOMID_SELF )
   14.76              d = rcu_lock_current_domain();
   14.77 -        else if ( !IS_PRIV(current->domain) )
   14.78 -            return -EPERM;
   14.79 -        else if ( (d = rcu_lock_domain_by_id(xatp.domid)) == NULL )
   14.80 -            return -ESRCH;
   14.81 +        else {
   14.82 +            d = rcu_lock_domain_by_id(xatp.domid);
   14.83 +            if ( d == NULL )
   14.84 +                return -ESRCH;
   14.85 +            if ( !IS_PRIV_FOR(current->domain, d) ) {
   14.86 +                rcu_unlock_domain(d);
   14.87 +                return -EPERM;
   14.88 +            }
   14.89 +        }
   14.90  
   14.91          if ( xsm_add_to_physmap(current->domain, d) )
   14.92          {
   14.93 @@ -3313,10 +3312,15 @@ long arch_memory_op(int op, XEN_GUEST_HA
   14.94  
   14.95          if ( fmap.domid == DOMID_SELF )
   14.96              d = rcu_lock_current_domain();
   14.97 -        else if ( !IS_PRIV(current->domain) )
   14.98 -            return -EPERM;
   14.99 -        else if ( (d = rcu_lock_domain_by_id(fmap.domid)) == NULL )
  14.100 -            return -ESRCH;
  14.101 +        else {
  14.102 +            d = rcu_lock_domain_by_id(fmap.domid);
  14.103 +            if ( d == NULL )
  14.104 +                return -ESRCH;
  14.105 +            if ( !IS_PRIV_FOR(current->domain, d) ) {
  14.106 +                rcu_unlock_domain(d);
  14.107 +                return -EPERM;
  14.108 +            }
  14.109 +        }
  14.110  
  14.111          rc = xsm_domain_memory_map(d);
  14.112          if ( rc )
    15.1 --- a/xen/arch/x86/mm/shadow/multi.c	Wed Jan 23 11:21:35 2008 +0000
    15.2 +++ b/xen/arch/x86/mm/shadow/multi.c	Wed Jan 23 13:21:44 2008 +0000
    15.3 @@ -993,11 +993,11 @@ shadow_get_page_from_l1e(shadow_l1e_t sl
    15.4      // not own, we let it succeed anyway.
    15.5      //
    15.6      if ( unlikely(!res) &&
    15.7 -         IS_PRIV(d) &&
    15.8           !shadow_mode_translate(d) &&
    15.9           mfn_valid(mfn = shadow_l1e_get_mfn(sl1e)) &&
   15.10           (owner = page_get_owner(mfn_to_page(mfn))) &&
   15.11 -         (d != owner) )
   15.12 +         (d != owner) &&
   15.13 +         IS_PRIV_FOR(d, owner))
   15.14      {
   15.15          res = get_page_from_l1e(sl1e, owner);
   15.16          SHADOW_PRINTK("privileged domain %d installs map of mfn %05lx "
    16.1 --- a/xen/arch/x86/setup.c	Wed Jan 23 11:21:35 2008 +0000
    16.2 +++ b/xen/arch/x86/setup.c	Wed Jan 23 13:21:44 2008 +0000
    16.3 @@ -959,6 +959,7 @@ void __init __start_xen(unsigned long mb
    16.4          panic("Error creating domain 0\n");
    16.5  
    16.6      dom0->is_privileged = 1;
    16.7 +    dom0->target = NULL;
    16.8  
    16.9      /* Grab the DOM0 command line. */
   16.10      cmdline = (char *)(mod[0].string ? __va(mod[0].string) : NULL);
    17.1 --- a/xen/common/domain.c	Wed Jan 23 11:21:35 2008 +0000
    17.2 +++ b/xen/common/domain.c	Wed Jan 23 13:21:44 2008 +0000
    17.3 @@ -502,6 +502,9 @@ static void complete_domain_destroy(stru
    17.4          if ( (v = d->vcpu[i]) != NULL )
    17.5              free_vcpu_struct(v);
    17.6  
    17.7 +    if (d->target)
    17.8 +        put_domain(d->target);
    17.9 +
   17.10      free_domain(d);
   17.11  
   17.12      send_guest_global_virq(dom0, VIRQ_DOM_EXC);
    18.1 --- a/xen/common/domctl.c	Wed Jan 23 11:21:35 2008 +0000
    18.2 +++ b/xen/common/domctl.c	Wed Jan 23 13:21:44 2008 +0000
    18.3 @@ -182,9 +182,6 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
    18.4      struct xen_domctl curop, *op = &curop;
    18.5      static DEFINE_SPINLOCK(domctl_lock);
    18.6  
    18.7 -    if ( !IS_PRIV(current->domain) )
    18.8 -        return -EPERM;
    18.9 -
   18.10      if ( copy_from_guest(op, u_domctl, 1) )
   18.11          return -EFAULT;
   18.12  
   18.13 @@ -207,6 +204,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
   18.14          if ( d == NULL )
   18.15              break;
   18.16  
   18.17 +        ret = -EPERM;
   18.18 +        if ( !IS_PRIV_FOR(current->domain, d) )
   18.19 +            goto svc_out;
   18.20 +
   18.21          ret = xsm_setvcpucontext(d);
   18.22          if ( ret )
   18.23              goto svc_out;
   18.24 @@ -258,6 +259,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
   18.25          ret = -ESRCH;
   18.26          if ( d != NULL )
   18.27          {
   18.28 +            ret = -EPERM;
   18.29 +            if ( !IS_PRIV_FOR(current->domain, d) )
   18.30 +                goto pausedomain_out;
   18.31 +
   18.32              ret = xsm_pausedomain(d);
   18.33              if ( ret )
   18.34                  goto pausedomain_out;
   18.35 @@ -282,16 +287,18 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
   18.36          if ( d == NULL )
   18.37              break;
   18.38  
   18.39 +        ret = -EPERM;
   18.40 +        if ( !IS_PRIV_FOR(current->domain, d) )
   18.41 +            goto unpausedomain_out;
   18.42 +
   18.43          ret = xsm_unpausedomain(d);
   18.44          if ( ret )
   18.45 -        {
   18.46 -            rcu_unlock_domain(d);
   18.47 -            break;
   18.48 -        }
   18.49 +            goto unpausedomain_out;
   18.50  
   18.51          domain_unpause_by_systemcontroller(d);
   18.52 +        ret = 0;
   18.53 +unpausedomain_out:
   18.54          rcu_unlock_domain(d);
   18.55 -        ret = 0;
   18.56      }
   18.57      break;
   18.58  
   18.59 @@ -303,16 +310,18 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
   18.60          if ( d == NULL )
   18.61              break;
   18.62  
   18.63 +        ret = -EPERM;
   18.64 +        if ( !IS_PRIV_FOR(current->domain, d) )
   18.65 +            goto resumedomain_out;
   18.66 +
   18.67          ret = xsm_resumedomain(d);
   18.68          if ( ret )
   18.69 -        {
   18.70 -            rcu_unlock_domain(d);
   18.71 -            break;
   18.72 -        }
   18.73 +            goto resumedomain_out;
   18.74  
   18.75          domain_resume(d);
   18.76 +        ret = 0;
   18.77 +resumedomain_out:
   18.78          rcu_unlock_domain(d);
   18.79 -        ret = 0;
   18.80      }
   18.81      break;
   18.82  
   18.83 @@ -323,6 +332,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
   18.84          static domid_t rover = 0;
   18.85          unsigned int domcr_flags;
   18.86  
   18.87 +        ret = -EPERM;
   18.88 +        if ( !IS_PRIV(current->domain) )
   18.89 +            break;
   18.90 +
   18.91          ret = -EINVAL;
   18.92          if ( supervisor_mode_kernel ||
   18.93               (op->u.createdomain.flags & ~XEN_DOMCTL_CDF_hvm_guest) )
   18.94 @@ -385,12 +398,13 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
   18.95          if ( (d = rcu_lock_domain_by_id(op->domain)) == NULL )
   18.96              break;
   18.97  
   18.98 +        ret = -EPERM;
   18.99 +        if ( !IS_PRIV_FOR(current->domain, d) )
  18.100 +            goto maxvcpu_out2;
  18.101 +
  18.102          ret = xsm_max_vcpus(d);
  18.103          if ( ret )
  18.104 -        {
  18.105 -            rcu_unlock_domain(d);
  18.106 -            break;
  18.107 -        }
  18.108 +            goto maxvcpu_out2;
  18.109  
  18.110          /* Needed, for example, to ensure writable p.t. state is synced. */
  18.111          domain_pause(d);
  18.112 @@ -418,6 +432,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
  18.113  
  18.114      maxvcpu_out:
  18.115          domain_unpause(d);
  18.116 +    maxvcpu_out2:
  18.117          rcu_unlock_domain(d);
  18.118      }
  18.119      break;
  18.120 @@ -428,7 +443,9 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
  18.121          ret = -ESRCH;
  18.122          if ( d != NULL )
  18.123          {
  18.124 -            ret = xsm_destroydomain(d) ? : domain_kill(d);
  18.125 +            ret = -EPERM;
  18.126 +            if ( IS_PRIV_FOR(current->domain, d) )
  18.127 +                ret = xsm_destroydomain(d) ? : domain_kill(d);
  18.128              rcu_unlock_domain(d);
  18.129          }
  18.130      }
  18.131 @@ -446,6 +463,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
  18.132          if ( d == NULL )
  18.133              break;
  18.134  
  18.135 +        ret = -EPERM;
  18.136 +        if ( !IS_PRIV_FOR(current->domain, d) )
  18.137 +            goto vcpuaffinity_out;
  18.138 +
  18.139          ret = xsm_vcpuaffinity(op->cmd, d);
  18.140          if ( ret )
  18.141              goto vcpuaffinity_out;
  18.142 @@ -484,6 +505,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
  18.143          if ( (d = rcu_lock_domain_by_id(op->domain)) == NULL )
  18.144              break;
  18.145  
  18.146 +        ret = -EPERM;
  18.147 +        if ( !IS_PRIV_FOR(current->domain, d) )
  18.148 +            goto scheduler_op_out;
  18.149 +
  18.150          ret = xsm_scheduler(d);
  18.151          if ( ret )
  18.152              goto scheduler_op_out;
  18.153 @@ -505,7 +530,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
  18.154          rcu_read_lock(&domlist_read_lock);
  18.155  
  18.156          for_each_domain ( d )
  18.157 -            if ( d->domain_id >= dom )
  18.158 +            if ( d->domain_id >= dom && IS_PRIV_FOR(current->domain, d))
  18.159                  break;
  18.160  
  18.161          if ( d == NULL )
  18.162 @@ -540,6 +565,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
  18.163          if ( (d = rcu_lock_domain_by_id(op->domain)) == NULL )
  18.164              break;
  18.165  
  18.166 +        ret = -EPERM;
  18.167 +        if ( !IS_PRIV_FOR(current->domain, d) )
  18.168 +            goto getvcpucontext_out;
  18.169 +
  18.170          ret = xsm_getvcpucontext(d);
  18.171          if ( ret )
  18.172              goto getvcpucontext_out;
  18.173 @@ -600,6 +629,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
  18.174          if ( (d = rcu_lock_domain_by_id(op->domain)) == NULL )
  18.175              break;
  18.176  
  18.177 +        ret = -EPERM;
  18.178 +        if ( !IS_PRIV_FOR(current->domain, d) )
  18.179 +            goto getvcpuinfo_out;
  18.180 +
  18.181          ret = xsm_getvcpuinfo(d);
  18.182          if ( ret )
  18.183              goto getvcpuinfo_out;
  18.184 @@ -639,6 +672,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
  18.185          if ( d == NULL )
  18.186              break;
  18.187  
  18.188 +        ret = -EPERM;
  18.189 +        if ( !IS_PRIV_FOR(current->domain, d) )
  18.190 +            goto max_mem_out;
  18.191 +
  18.192          ret = xsm_setdomainmaxmem(d);
  18.193          if ( ret )
  18.194              goto max_mem_out;
  18.195 @@ -655,6 +692,8 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
  18.196              d->max_pages = new_max;
  18.197              ret = 0;
  18.198          }
  18.199 +        else
  18.200 +            printk("new max %ld, tot pages %d\n", new_max, d->tot_pages);
  18.201          spin_unlock(&d->page_alloc_lock);
  18.202  
  18.203      max_mem_out:
  18.204 @@ -671,17 +710,19 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
  18.205          if ( d == NULL )
  18.206              break;
  18.207  
  18.208 +        ret = -EPERM;
  18.209 +        if ( !IS_PRIV_FOR(current->domain, d) )
  18.210 +            goto setdomainhandle_out;
  18.211 +
  18.212          ret = xsm_setdomainhandle(d);
  18.213          if ( ret )
  18.214 -        {
  18.215 -            rcu_unlock_domain(d);
  18.216 -            break;
  18.217 -        }
  18.218 +            goto setdomainhandle_out;
  18.219  
  18.220          memcpy(d->handle, op->u.setdomainhandle.handle,
  18.221                 sizeof(xen_domain_handle_t));
  18.222 +        ret = 0;
  18.223 +setdomainhandle_out:
  18.224          rcu_unlock_domain(d);
  18.225 -        ret = 0;
  18.226      }
  18.227      break;
  18.228  
  18.229 @@ -694,18 +735,20 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
  18.230          if ( d == NULL )
  18.231              break;
  18.232  
  18.233 +        ret = -EPERM;
  18.234 +        if ( !IS_PRIV_FOR(current->domain, d) )
  18.235 +            goto setdebugging_out;
  18.236 +
  18.237          ret = xsm_setdebugging(d);
  18.238          if ( ret )
  18.239 -        {
  18.240 -            rcu_unlock_domain(d);
  18.241 -            break;
  18.242 -        }
  18.243 +            goto setdebugging_out;
  18.244  
  18.245          domain_pause(d);
  18.246          d->debugger_attached = !!op->u.setdebugging.enable;
  18.247          domain_unpause(d); /* causes guest to latch new status */
  18.248 +        ret = 0;
  18.249 +setdebugging_out:
  18.250          rcu_unlock_domain(d);
  18.251 -        ret = 0;
  18.252      }
  18.253      break;
  18.254  
  18.255 @@ -723,6 +766,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
  18.256          if ( d == NULL )
  18.257              break;
  18.258  
  18.259 +        ret = -EPERM;
  18.260 +        if ( !IS_PRIV_FOR(current->domain, d) )
  18.261 +            goto irq_permission_out;
  18.262 +
  18.263          ret = xsm_irq_permission(d, pirq, op->u.irq_permission.allow_access);
  18.264          if ( ret )
  18.265              goto irq_permission_out;
  18.266 @@ -752,6 +799,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
  18.267          if ( d == NULL )
  18.268              break;
  18.269  
  18.270 +        ret = -EPERM;
  18.271 +        if ( !IS_PRIV_FOR(current->domain, d) )
  18.272 +            goto iomem_permission_out;
  18.273 +
  18.274          ret = xsm_iomem_permission(d, mfn, op->u.iomem_permission.allow_access);
  18.275          if ( ret )
  18.276              goto iomem_permission_out;
  18.277 @@ -772,19 +823,61 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
  18.278  
  18.279          ret = -ESRCH;
  18.280          d = rcu_lock_domain_by_id(op->domain);
  18.281 -        if ( d != NULL )
  18.282 -        {
  18.283 -            ret = xsm_domain_settime(d);
  18.284 -            if ( ret )
  18.285 -            {
  18.286 -                rcu_unlock_domain(d);
  18.287 -                break;
  18.288 -            }
  18.289 +        if ( d == NULL )
  18.290 +            break;
  18.291  
  18.292 -            d->time_offset_seconds = op->u.settimeoffset.time_offset_seconds;
  18.293 -            rcu_unlock_domain(d);
  18.294 -            ret = 0;
  18.295 +        ret = -EPERM;
  18.296 +        if ( !IS_PRIV_FOR(current->domain, d) )
  18.297 +            goto settimeoffset_out;
  18.298 +
  18.299 +        ret = xsm_domain_settime(d);
  18.300 +        if ( ret )
  18.301 +            goto settimeoffset_out;
  18.302 +
  18.303 +        d->time_offset_seconds = op->u.settimeoffset.time_offset_seconds;
  18.304 +
  18.305 +        ret = 0;
  18.306 +settimeoffset_out:
  18.307 +        rcu_unlock_domain(d);
  18.308 +    }
  18.309 +    break;
  18.310 +
  18.311 +    case XEN_DOMCTL_set_target:
  18.312 +    {
  18.313 +        struct domain *d, *e;
  18.314 +
  18.315 +        ret = -ESRCH;
  18.316 +        d = rcu_lock_domain_by_id(op->domain);
  18.317 +        if ( d == NULL )
  18.318 +            break;
  18.319 +
  18.320 +        ret = -EPERM;
  18.321 +        if (!IS_PRIV_FOR(current->domain, d))
  18.322 +            goto set_target_out;
  18.323 +
  18.324 +        ret = -ESRCH;
  18.325 +        e = get_domain_by_id(op->u.set_target.target);
  18.326 +        if ( e == NULL )
  18.327 +            goto set_target_out;
  18.328 +
  18.329 +        if ( d == e ) {
  18.330 +            ret = -EINVAL;
  18.331 +            put_domain(e);
  18.332 +            goto set_target_out;
  18.333          }
  18.334 +
  18.335 +        if (!IS_PRIV_FOR(current->domain, e)) {
  18.336 +            ret = -EPERM;
  18.337 +            put_domain(e);
  18.338 +            goto set_target_out;
  18.339 +        }
  18.340 +
  18.341 +        d->target = e;
  18.342 +        /* and we keep the reference on e, released when destroying d */
  18.343 +        ret = 0;
  18.344 +
  18.345 +set_target_out:
  18.346 +        rcu_unlock_domain(d);
  18.347      }
  18.348      break;
  18.349  
    19.1 --- a/xen/common/event_channel.c	Wed Jan 23 11:21:35 2008 +0000
    19.2 +++ b/xen/common/event_channel.c	Wed Jan 23 13:21:44 2008 +0000
    19.3 @@ -130,12 +130,15 @@ static long evtchn_alloc_unbound(evtchn_
    19.4      long           rc;
    19.5  
    19.6      if ( dom == DOMID_SELF )
    19.7 -        dom = current->domain->domain_id;
    19.8 -    else if ( !IS_PRIV(current->domain) )
    19.9 -        return -EPERM;
   19.10 -
   19.11 -    if ( (d = rcu_lock_domain_by_id(dom)) == NULL )
   19.12 -        return -ESRCH;
   19.13 +        d = current->domain;
   19.14 +    else {
   19.15 +        if ( (d = rcu_lock_domain_by_id(dom)) == NULL )
   19.16 +            return -ESRCH;
   19.17 +        if ( !IS_PRIV_FOR(current->domain, d) ) {
   19.18 +            rc = -EPERM;
   19.19 +            goto out2;
   19.20 +        }
   19.21 +    }
   19.22  
   19.23      spin_lock(&d->evtchn_lock);
   19.24  
   19.25 @@ -156,6 +159,7 @@ static long evtchn_alloc_unbound(evtchn_
   19.26   out:
   19.27      spin_unlock(&d->evtchn_lock);
   19.28  
   19.29 + out2:
   19.30      rcu_unlock_domain(d);
   19.31  
   19.32      return rc;
   19.33 @@ -197,7 +201,7 @@ static long evtchn_bind_interdomain(evtc
   19.34          ERROR_EXIT_DOM(-EINVAL, rd);
   19.35      rchn = evtchn_from_port(rd, rport);
   19.36      if ( (rchn->state != ECS_UNBOUND) ||
   19.37 -         (rchn->u.unbound.remote_domid != ld->domain_id) )
   19.38 +            (rchn->u.unbound.remote_domid != ld->domain_id && !IS_PRIV_FOR(ld, rd)))
   19.39          ERROR_EXIT_DOM(-EINVAL, rd);
   19.40  
   19.41      rc = xsm_evtchn_interdomain(ld, lchn, rd, rchn);
   19.42 @@ -628,12 +632,15 @@ static long evtchn_status(evtchn_status_
   19.43      long             rc = 0;
   19.44  
   19.45      if ( dom == DOMID_SELF )
   19.46 -        dom = current->domain->domain_id;
   19.47 -    else if ( !IS_PRIV(current->domain) )
   19.48 -        return -EPERM;
   19.49 -
   19.50 -    if ( (d = rcu_lock_domain_by_id(dom)) == NULL )
   19.51 -        return -ESRCH;
   19.52 +        d = current->domain;
   19.53 +    else {
   19.54 +        if ( (d = rcu_lock_domain_by_id(dom)) == NULL )
   19.55 +            return -ESRCH;
   19.56 +        if ( !IS_PRIV_FOR(current->domain, d) ) {
   19.57 +            rc = -EPERM;
   19.58 +            goto out2;
   19.59 +        }
   19.60 +    }
   19.61  
   19.62      spin_lock(&d->evtchn_lock);
   19.63  
   19.64 @@ -684,6 +691,7 @@ static long evtchn_status(evtchn_status_
   19.65  
   19.66   out:
   19.67      spin_unlock(&d->evtchn_lock);
   19.68 + out2:
   19.69      rcu_unlock_domain(d);
   19.70      return rc;
   19.71  }
   19.72 @@ -782,26 +790,28 @@ static long evtchn_reset(evtchn_reset_t 
   19.73      int rc;
   19.74  
   19.75      if ( dom == DOMID_SELF )
   19.76 -        dom = current->domain->domain_id;
   19.77 -    else if ( !IS_PRIV(current->domain) )
   19.78 -        return -EPERM;
   19.79 -
   19.80 -    if ( (d = rcu_lock_domain_by_id(dom)) == NULL )
   19.81 -        return -ESRCH;
   19.82 +        d = current->domain;
   19.83 +    else {
   19.84 +        if ( (d = rcu_lock_domain_by_id(dom)) == NULL )
   19.85 +            return -ESRCH;
   19.86 +        if ( !IS_PRIV_FOR(current->domain, d) ) {
   19.87 +            rc = -EPERM;
   19.88 +            goto out;
   19.89 +        }
   19.90 +    }
   19.91  
   19.92      rc = xsm_evtchn_reset(current->domain, d);
   19.93      if ( rc )
   19.94 -    {
   19.95 -        rcu_unlock_domain(d);
   19.96 -        return rc;
   19.97 -    }
   19.98 +        goto out;
   19.99  
  19.100      for ( i = 0; port_is_valid(d, i); i++ )
  19.101          (void)__evtchn_close(d, i);
  19.102  
  19.103 +    rc = 0;
  19.104 +out:
  19.105      rcu_unlock_domain(d);
  19.106  
  19.107 -    return 0;
  19.108 +    return rc;
  19.109  }
  19.110  
  19.111  
    20.1 --- a/xen/common/grant_table.c	Wed Jan 23 11:21:35 2008 +0000
    20.2 +++ b/xen/common/grant_table.c	Wed Jan 23 13:21:44 2008 +0000
    20.3 @@ -834,19 +834,19 @@ gnttab_setup_table(
    20.4      dom = op.dom;
    20.5      if ( dom == DOMID_SELF )
    20.6      {
    20.7 -        dom = current->domain->domain_id;
    20.8 +        d = current->domain;
    20.9      }
   20.10 -    else if ( unlikely(!IS_PRIV(current->domain)) )
   20.11 -    {
   20.12 -        op.status = GNTST_permission_denied;
   20.13 -        goto out;
   20.14 -    }
   20.15 -
   20.16 -    if ( unlikely((d = rcu_lock_domain_by_id(dom)) == NULL) )
   20.17 -    {
   20.18 -        gdprintk(XENLOG_INFO, "Bad domid %d.\n", dom);
   20.19 -        op.status = GNTST_bad_domain;
   20.20 -        goto out;
   20.21 +    else {
   20.22 +        if ( unlikely((d = rcu_lock_domain_by_id(dom)) == NULL) )
   20.23 +        {
   20.24 +            gdprintk(XENLOG_INFO, "Bad domid %d.\n", dom);
   20.25 +            op.status = GNTST_bad_domain;
   20.26 +            goto out;
   20.27 +        }
   20.28 +        if ( unlikely(!IS_PRIV_FOR(current->domain, d)) ) {
   20.29 +            op.status = GNTST_permission_denied;
   20.30 +            goto setup_unlock_out2;
   20.31 +        }
   20.32      }
   20.33  
   20.34      if ( xsm_grant_setup(current->domain, d) )
   20.35 @@ -880,6 +880,7 @@ gnttab_setup_table(
   20.36   setup_unlock_out:
   20.37      spin_unlock(&d->grant_table->lock);
   20.38  
   20.39 + setup_unlock_out2:
   20.40      rcu_unlock_domain(d);
   20.41  
   20.42   out:
   20.43 @@ -910,27 +911,26 @@ gnttab_query_size(
   20.44      dom = op.dom;
   20.45      if ( dom == DOMID_SELF )
   20.46      {
   20.47 -        dom = current->domain->domain_id;
   20.48 +        d = current->domain;
   20.49      }
   20.50 -    else if ( unlikely(!IS_PRIV(current->domain)) )
   20.51 -    {
   20.52 -        op.status = GNTST_permission_denied;
   20.53 -        goto query_out;
   20.54 -    }
   20.55 -
   20.56 -    if ( unlikely((d = rcu_lock_domain_by_id(dom)) == NULL) )
   20.57 -    {
   20.58 -        gdprintk(XENLOG_INFO, "Bad domid %d.\n", dom);
   20.59 -        op.status = GNTST_bad_domain;
   20.60 -        goto query_out;
   20.61 +    else {
   20.62 +        if ( unlikely((d = rcu_lock_domain_by_id(dom)) == NULL) )
   20.63 +        {
   20.64 +            gdprintk(XENLOG_INFO, "Bad domid %d.\n", dom);
   20.65 +            op.status = GNTST_bad_domain;
   20.66 +            goto query_out;
   20.67 +        }
   20.68 +        if ( unlikely(!IS_PRIV_FOR(current->domain, d)) ) {
   20.69 +            op.status = GNTST_permission_denied;
   20.70 +            goto query_out_unlock;
   20.71 +        }
   20.72      }
   20.73  
   20.74      rc = xsm_grant_query_size(current->domain, d);
   20.75      if ( rc )
   20.76      {
   20.77 -        rcu_unlock_domain(d);
   20.78          op.status = GNTST_permission_denied;
   20.79 -        goto query_out;
   20.80 +        goto query_out_unlock;
   20.81      }
   20.82  
   20.83      spin_lock(&d->grant_table->lock);
   20.84 @@ -941,6 +941,8 @@ gnttab_query_size(
   20.85  
   20.86      spin_unlock(&d->grant_table->lock);
   20.87  
   20.88 + 
   20.89 + query_out_unlock:
   20.90      rcu_unlock_domain(d);
   20.91  
   20.92   query_out:
    21.1 --- a/xen/common/memory.c	Wed Jan 23 11:21:35 2008 +0000
    21.2 +++ b/xen/common/memory.c	Wed Jan 23 13:21:44 2008 +0000
    21.3 @@ -232,12 +232,17 @@ static long translate_gpfn_list(
    21.4          return -EFAULT;
    21.5  
    21.6      if ( op.domid == DOMID_SELF )
    21.7 -        op.domid = current->domain->domain_id;
    21.8 -    else if ( !IS_PRIV(current->domain) )
    21.9 -        return -EPERM;
   21.10 +        d = current->domain;
   21.11 +    else {
   21.12 +        d = rcu_lock_domain_by_id(op.domid);
   21.13 +        if ( d == NULL )
   21.14 +            return -ESRCH;
   21.15 +        if ( !IS_PRIV_FOR(current->domain, d) ) {
   21.16 +            rcu_unlock_domain(d);
   21.17 +            return -EPERM;
   21.18 +        }
   21.19 +    }
   21.20  
   21.21 -    if ( (d = rcu_lock_domain_by_id(op.domid)) == NULL )
   21.22 -        return -ESRCH;
   21.23  
   21.24      if ( !paging_mode_translate(d) )
   21.25      {
   21.26 @@ -535,9 +540,15 @@ long do_memory_op(unsigned long cmd, XEN
   21.27  
   21.28          if ( likely(reservation.domid == DOMID_SELF) )
   21.29              d = current->domain;
   21.30 -        else if ( !IS_PRIV(current->domain) ||
   21.31 -                  ((d = rcu_lock_domain_by_id(reservation.domid)) == NULL) )
   21.32 -            return start_extent;
   21.33 +        else {
   21.34 +            d = rcu_lock_domain_by_id(reservation.domid);
   21.35 +            if ( d == NULL)
   21.36 +                return start_extent;
   21.37 +            if ( !IS_PRIV_FOR(current->domain, d) ) {
   21.38 +                rcu_unlock_domain(d);
   21.39 +                return start_extent;
   21.40 +            }
   21.41 +        }
   21.42          args.domain = d;
   21.43  
   21.44          rc = xsm_memory_adjust_reservation(current->domain, d);
   21.45 @@ -589,10 +600,15 @@ long do_memory_op(unsigned long cmd, XEN
   21.46  
   21.47          if ( likely(domid == DOMID_SELF) )
   21.48              d = current->domain;
   21.49 -        else if ( !IS_PRIV(current->domain) )
   21.50 -            return -EPERM;
   21.51 -        else if ( (d = rcu_lock_domain_by_id(domid)) == NULL )
   21.52 -            return -ESRCH;
   21.53 +        else {
   21.54 +            d = rcu_lock_domain_by_id(domid);
   21.55 +            if ( d == NULL )
   21.56 +                return -ESRCH;
   21.57 +            if ( !IS_PRIV_FOR(current->domain, d) ) {
   21.58 +                rcu_unlock_domain(d);
   21.59 +                return -EPERM;
   21.60 +            }
   21.61 +        }
   21.62  
   21.63          rc = xsm_memory_stat_reservation(current->domain, d);
   21.64          if ( rc )
    22.1 --- a/xen/common/schedule.c	Wed Jan 23 11:21:35 2008 +0000
    22.2 +++ b/xen/common/schedule.c	Wed Jan 23 13:21:44 2008 +0000
    22.3 @@ -461,9 +461,6 @@ ret_t do_sched_op(int cmd, XEN_GUEST_HAN
    22.4          struct domain *d;
    22.5          struct sched_remote_shutdown sched_remote_shutdown;
    22.6  
    22.7 -        if ( !IS_PRIV(current->domain) )
    22.8 -            return -EPERM;
    22.9 -
   22.10          ret = -EFAULT;
   22.11          if ( copy_from_guest(&sched_remote_shutdown, arg, 1) )
   22.12              break;
   22.13 @@ -473,6 +470,12 @@ ret_t do_sched_op(int cmd, XEN_GUEST_HAN
   22.14          if ( d == NULL )
   22.15              break;
   22.16  
   22.17 +        if ( !IS_PRIV_FOR(current->domain, d) )
   22.18 +        {
   22.19 +            rcu_unlock_domain(d);
   22.20 +            return -EPERM;
   22.21 +        }
   22.22 +
   22.23          ret = xsm_schedop_shutdown(current->domain, d);
   22.24          if ( ret )
   22.25          {
    23.1 --- a/xen/include/public/domctl.h	Wed Jan 23 11:21:35 2008 +0000
    23.2 +++ b/xen/include/public/domctl.h	Wed Jan 23 13:21:44 2008 +0000
    23.3 @@ -554,6 +554,17 @@ struct xen_domctl_set_opt_feature {
    23.4  typedef struct xen_domctl_set_opt_feature xen_domctl_set_opt_feature_t;
    23.5  DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_opt_feature_t);
    23.6  
    23.7 +/*
    23.8 + * Set the target domain for a domain
    23.9 + */
   23.10 +#define XEN_DOMCTL_set_target    46
   23.11 +struct xen_domctl_set_target {
   23.12 +    domid_t target;
   23.13 +};
   23.14 +typedef struct xen_domctl_set_target xen_domctl_set_target_t;
   23.15 +DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_target_t);
   23.16 +
   23.17 +
   23.18  struct xen_domctl {
   23.19      uint32_t cmd;
   23.20      uint32_t interface_version; /* XEN_DOMCTL_INTERFACE_VERSION */
   23.21 @@ -590,6 +601,7 @@ struct xen_domctl {
   23.22          struct xen_domctl_pin_mem_cacheattr pin_mem_cacheattr;
   23.23          struct xen_domctl_ext_vcpucontext   ext_vcpucontext;
   23.24          struct xen_domctl_set_opt_feature   set_opt_feature;
   23.25 +        struct xen_domctl_set_target        set_target;
   23.26          uint8_t                             pad[128];
   23.27      } u;
   23.28  };
    24.1 --- a/xen/include/xen/sched.h	Wed Jan 23 11:21:35 2008 +0000
    24.2 +++ b/xen/include/xen/sched.h	Wed Jan 23 13:21:44 2008 +0000
    24.3 @@ -187,6 +187,8 @@ struct domain
    24.4      bool_t           is_hvm;
    24.5      /* Is this guest fully privileged (aka dom0)? */
    24.6      bool_t           is_privileged;
    24.7 +    /* Which guest this guest has privileges on */
    24.8 +    struct domain   *target;
    24.9      /* Is this guest being debugged by dom0? */
   24.10      bool_t           debugger_attached;
   24.11      /* Are any VCPUs polling event channels (SCHEDOP_poll)? */
   24.12 @@ -493,6 +495,7 @@ static inline void vcpu_unblock(struct v
   24.13  }
   24.14  
   24.15  #define IS_PRIV(_d) ((_d)->is_privileged)
   24.16 +#define IS_PRIV_FOR(_d, _t) (IS_PRIV(_d) || ((_d)->target && (_d)->target == (_t)))
   24.17  
   24.18  #ifndef IS_COMPAT
   24.19  #define IS_COMPAT(d) 0
    25.1 --- a/xen/xsm/acm/acm_simple_type_enforcement_hooks.c	Wed Jan 23 11:21:35 2008 +0000
    25.2 +++ b/xen/xsm/acm/acm_simple_type_enforcement_hooks.c	Wed Jan 23 13:21:44 2008 +0000
    25.3 @@ -817,17 +817,19 @@ ste_pre_grant_setup (domid_t id)
    25.4          return ACM_ACCESS_PERMITTED;
    25.5      }
    25.6      atomic_inc(&ste_bin_pol.gt_eval_count);
    25.7 +    subj = current->domain;
    25.8 +    obj = rcu_lock_domain_by_id(id);
    25.9 +
   25.10      /* a) check authorization (eventually use specific capabilities) */
   25.11 -    if ( !IS_PRIV(current->domain) )
   25.12 +    if ( obj && !IS_PRIV_FOR(current->domain, obj) )
   25.13      {
   25.14          printk("%s: Grant table management authorization denied ERROR!\n",
   25.15                 __func__);
   25.16 +        rcu_unlock_domain(obj);
   25.17          return ACM_ACCESS_DENIED;
   25.18      }
   25.19 +
   25.20      /* b) check types */
   25.21 -    subj = current->domain;
   25.22 -    obj = rcu_lock_domain_by_id(id);
   25.23 -
   25.24      if ( share_common_type(subj, obj) )
   25.25      {
   25.26          cache_result(subj, obj);