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] [xen-unstable] New XEN_DOMCTL_set_target

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] New XEN_DOMCTL_set_target
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 23 Jan 2008 10:20:14 -0800
Delivery-date: Wed, 23 Jan 2008 10:20:51 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1201094504 0
# Node ID cff4c8a1aa28fa8856d61969618f8db9075e593c
# Parent  bcae9d2cc2f8d8d8519f2c211e80cf4d0fee3ca5
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@xxxxxxxxxxxxx>
---
 tools/libxc/xc_domain.c                         |   14 +
 tools/libxc/xenctrl.h                           |    5 
 tools/python/xen/lowlevel/xc/xc.c               |   15 +
 tools/python/xen/xend/XendConfig.py             |    7 
 tools/python/xen/xend/XendDomainInfo.py         |    3 
 tools/python/xen/xm/create.py                   |    6 
 xen/arch/ia64/vmx/vmx_hypercall.c               |   22 +-
 xen/arch/ia64/xen/dom0_ops.c                    |   46 +++++
 xen/arch/ia64/xen/hypercall.c                   |    7 
 xen/arch/ia64/xen/mm.c                          |   12 +
 xen/arch/ia64/xen/xensetup.c                    |    1 
 xen/arch/powerpc/setup.c                        |    1 
 xen/arch/x86/hvm/hvm.c                          |   36 ++--
 xen/arch/x86/mm.c                               |   78 +++++-----
 xen/arch/x86/mm/shadow/multi.c                  |    4 
 xen/arch/x86/setup.c                            |    1 
 xen/common/domain.c                             |    3 
 xen/common/domctl.c                             |  185 ++++++++++++++++++------
 xen/common/event_channel.c                      |   58 ++++---
 xen/common/grant_table.c                        |   58 +++----
 xen/common/memory.c                             |   42 +++--
 xen/common/schedule.c                           |    9 -
 xen/include/public/domctl.h                     |   12 +
 xen/include/xen/sched.h                         |    3 
 xen/xsm/acm/acm_simple_type_enforcement_hooks.c |   10 -
 25 files changed, 439 insertions(+), 199 deletions(-)

diff -r bcae9d2cc2f8 -r cff4c8a1aa28 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c   Wed Jan 23 11:21:35 2008 +0000
+++ b/tools/libxc/xc_domain.c   Wed Jan 23 13:21:44 2008 +0000
@@ -875,6 +875,20 @@ int xc_domain_ioport_mapping(
     return do_domctl(xc_handle, &domctl);
 }
 
+int xc_domain_set_target(
+    int xc_handle,
+    uint32_t domid,
+    uint32_t target)
+{
+    DECLARE_DOMCTL;
+
+    domctl.cmd = XEN_DOMCTL_set_target;
+    domctl.domain = domid;
+    domctl.u.set_target.target = target;
+
+    return do_domctl(xc_handle, &domctl);
+}
+
 /*
  * Local variables:
  * mode: C
diff -r bcae9d2cc2f8 -r cff4c8a1aa28 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Wed Jan 23 11:21:35 2008 +0000
+++ b/tools/libxc/xenctrl.h     Wed Jan 23 13:21:44 2008 +0000
@@ -952,4 +952,9 @@ int xc_domain_bind_pt_isa_irq(int xc_han
                               uint32_t domid,
                               uint8_t machine_irq);
 
+/* Set the target domain */
+int xc_domain_set_target(int xc_handle,
+                         uint32_t domid,
+                         uint32_t target);
+
 #endif /* XENCTRL_H */
diff -r bcae9d2cc2f8 -r cff4c8a1aa28 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Wed Jan 23 11:21:35 2008 +0000
+++ b/tools/python/xen/lowlevel/xc/xc.c Wed Jan 23 13:21:44 2008 +0000
@@ -96,17 +96,17 @@ static PyObject *pyxc_domain_create(XcOb
                                     PyObject *args,
                                     PyObject *kwds)
 {
-    uint32_t dom = 0, ssidref = 0, flags = 0;
+    uint32_t dom = 0, ssidref = 0, flags = 0, target = 0;
     int      ret, i, hvm = 0;
     PyObject *pyhandle = NULL;
     xen_domain_handle_t handle = { 
         0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
         0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef };
 
-    static char *kwd_list[] = { "domid", "ssidref", "handle", "hvm", NULL };
-
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiOi", kwd_list,
-                                      &dom, &ssidref, &pyhandle, &hvm))
+    static char *kwd_list[] = { "domid", "ssidref", "handle", "hvm", "target", 
NULL };
+
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiOii", kwd_list,
+                                     &dom, &ssidref, &pyhandle, &hvm, &target))
         return NULL;
 
     if ( pyhandle != NULL )
@@ -130,6 +130,11 @@ static PyObject *pyxc_domain_create(XcOb
     if ( (ret = xc_domain_create(self->xc_handle, ssidref,
                                  handle, flags, &dom)) < 0 )
         return pyxc_error_to_exception();
+
+    if ( target )
+        if ( (ret = xc_domain_set_target(self->xc_handle, dom, target)) < 0 )
+            return pyxc_error_to_exception();
+
 
     return PyInt_FromLong(dom);
 
diff -r bcae9d2cc2f8 -r cff4c8a1aa28 tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Wed Jan 23 11:21:35 2008 +0000
+++ b/tools/python/xen/xend/XendConfig.py       Wed Jan 23 13:21:44 2008 +0000
@@ -170,6 +170,7 @@ XENAPI_CFG_TYPES = {
     'platform': dict,
     'tools_version': dict,
     'other_config': dict,
+    'target': int,
     'security_label': str,
     'pci': str,
 }
@@ -336,7 +337,8 @@ class XendConfig(dict):
             'vbd_refs': [],
             'vtpm_refs': [],
             'other_config': {},
-            'platform': {}
+            'platform': {},
+            'target': 0,
         }
         
         return defaults
@@ -1585,6 +1587,9 @@ class XendConfig(dict):
     def is_hvm(self):
         return self['HVM_boot_policy'] != ''
 
+    def target(self):
+       return self['target']
+
     def image_type(self):
         stored_type = self['platform'].get('image_type')
         return stored_type or (self.is_hvm() and 'hvm' or 'linux')
diff -r bcae9d2cc2f8 -r cff4c8a1aa28 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Wed Jan 23 11:21:35 2008 +0000
+++ b/tools/python/xen/xend/XendDomainInfo.py   Wed Jan 23 13:21:44 2008 +0000
@@ -1640,7 +1640,8 @@ class XendDomainInfo:
                 domid = 0,
                 ssidref = ssidref,
                 handle = uuid.fromString(self.info['uuid']),
-                hvm = int(hvm))
+                hvm = int(hvm),
+                target = self.info.target())
         except Exception, e:
             # may get here if due to ACM the operation is not permitted
             if security.on():
diff -r bcae9d2cc2f8 -r cff4c8a1aa28 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Wed Jan 23 11:21:35 2008 +0000
+++ b/tools/python/xen/xm/create.py     Wed Jan 23 13:21:44 2008 +0000
@@ -520,6 +520,10 @@ gopts.var('on_xend_stop', val='ignore|sh
           - shutdown:       Domain is shutdown;
           - suspend:        Domain is suspended;
           """)
+
+gopts.var('target', val='TARGET',
+          fn=set_int, default=0,
+          use="Set domain target.")
 
 def err(msg):
     """Print an error to stderr and exit.
@@ -748,7 +752,7 @@ def make_config(vals):
     map(add_conf, ['name', 'memory', 'maxmem', 'shadow_memory',
                    'restart', 'on_poweroff',
                    'on_reboot', 'on_crash', 'vcpus', 'vcpu_avail', 'features',
-                   'on_xend_start', 'on_xend_stop'])
+                   'on_xend_start', 'on_xend_stop', 'target'])
 
     if vals.uuid is not None:
         config.append(['uuid', vals.uuid])
diff -r bcae9d2cc2f8 -r cff4c8a1aa28 xen/arch/ia64/vmx/vmx_hypercall.c
--- a/xen/arch/ia64/vmx/vmx_hypercall.c Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/arch/ia64/vmx/vmx_hypercall.c Wed Jan 23 13:21:44 2008 +0000
@@ -47,15 +47,16 @@ static int hvmop_set_isa_irq_level(
     if ( copy_from_guest(&op, uop, 1) )
         return -EFAULT;
 
-    if ( !IS_PRIV(current->domain) )
-        return -EPERM;
-
     if ( op.isa_irq > 15 )
         return -EINVAL;
 
     d = rcu_lock_domain_by_id(op.domid);
     if ( d == NULL )
         return -ESRCH;
+
+    rc = -EPERM;
+    if ( !IS_PRIV_FOR(current->domain, d) )
+        goto out;
 
     rc = -EINVAL;
     if ( !is_hvm_domain(d) )
@@ -79,15 +80,16 @@ static int hvmop_set_pci_intx_level(
     if ( copy_from_guest(&op, uop, 1) )
         return -EFAULT;
 
-    if ( !IS_PRIV(current->domain) )
-        return -EPERM;
-
     if ( (op.domain > 0) || (op.bus > 0) || (op.device > 31) || (op.intx > 3) )
         return -EINVAL;
 
     d = rcu_lock_domain_by_id(op.domid);
     if ( d == NULL )
         return -ESRCH;
+
+    rc = -EPERM;
+    if ( !IS_PRIV_FOR(current->domain, d) )
+        goto out;
 
     rc = -EINVAL;
     if ( !is_hvm_domain(d) )
@@ -124,13 +126,15 @@ do_hvm_op(unsigned long op, XEN_GUEST_HA
         if (a.domid == DOMID_SELF) {
             d = rcu_lock_current_domain();
         }
-        else if (IS_PRIV(current->domain)) {
+        else {
             d = rcu_lock_domain_by_id(a.domid);
             if (d == NULL)
                 return -ESRCH;
+            if (!IS_PRIV_FOR(current->domain, d)) {
+                rcu_unlock_domain(d);
+                return -EPERM;
+            }
         }
-        else
-            return -EPERM;
 
         if (op == HVMOP_set_param) {
             struct vmx_ioreq_page *iorp;
diff -r bcae9d2cc2f8 -r cff4c8a1aa28 xen/arch/ia64/xen/dom0_ops.c
--- a/xen/arch/ia64/xen/dom0_ops.c      Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/arch/ia64/xen/dom0_ops.c      Wed Jan 23 13:21:44 2008 +0000
@@ -37,9 +37,6 @@ long arch_do_domctl(xen_domctl_t *op, XE
 {
     long ret = 0;
 
-    if ( !IS_PRIV(current->domain) )
-        return -EPERM;
-
     switch ( op->cmd )
     {
     case XEN_DOMCTL_getmemlist:
@@ -54,6 +51,13 @@ long arch_do_domctl(xen_domctl_t *op, XE
             ret = -EINVAL;
             break;
         }
+
+        if ( !IS_PRIV_FOR(current->domain, d) ) {
+            ret = -EPERM;
+            rcu_unlock_domain(d);
+            break;
+        }
+
         for (i = 0 ; i < nr_pages ; i++) {
             pte_t *pte;
 
@@ -84,6 +88,12 @@ long arch_do_domctl(xen_domctl_t *op, XE
 
         if ( d == NULL) {
             ret = -EINVAL;
+            break;
+        }
+
+        if ( !IS_PRIV_FOR(current->domain, d) ) {
+            ret = -EPERM;
+            rcu_unlock_domain(d);
             break;
         }
 
@@ -153,6 +163,12 @@ long arch_do_domctl(xen_domctl_t *op, XE
         d = rcu_lock_domain_by_id(op->domain);
         if ( d != NULL )
         {
+            if ( !IS_PRIV_FOR(current->domain, d) ) {
+                ret = -EPERM;
+                rcu_unlock_domain(d);
+                break;
+            }
+
             ret = shadow_mode_control(d, &op->u.shadow_op);
             rcu_unlock_domain(d);
             if (copy_to_guest(u_domctl, op, 1))
@@ -172,6 +188,12 @@ long arch_do_domctl(xen_domctl_t *op, XE
         d = rcu_lock_domain_by_id(op->domain);
         if (unlikely(d == NULL))
             break;
+
+        if ( !IS_PRIV_FOR(current->domain, d) ) {
+            ret = -EPERM;
+            rcu_unlock_domain(d);
+            break;
+        }
 
         if (np == 0)
             ret = 0;
@@ -195,6 +217,11 @@ long arch_do_domctl(xen_domctl_t *op, XE
         d = rcu_lock_domain_by_id(op->domain);
         if ( d == NULL )
             break;
+
+        ret = -EPERM;
+        if ( !IS_PRIV_FOR(current->domain, d) ) {
+            goto sendtrigger_out;
+        }
 
         ret = -EINVAL;
         if ( op->u.sendtrigger.vcpu >= MAX_VIRT_CPUS )
@@ -239,6 +266,10 @@ long arch_do_domctl(xen_domctl_t *op, XE
         if (d == NULL)
             break;
 
+        ret = -EPERM;
+        if ( !IS_PRIV_FOR(current->domain, d) )
+            goto sethvmcontext_out;
+
 #ifdef CONFIG_X86
         ret = xsm_hvmcontext(d, op->cmd);
         if (ret)
@@ -280,6 +311,10 @@ long arch_do_domctl(xen_domctl_t *op, XE
         if (d == NULL)
             break;
 
+        ret = -EPERM;
+        if ( !IS_PRIV_FOR(current->domain, d) )
+            goto gethvmcontext_out;
+
 #ifdef CONFIG_X86
         ret = xsm_hvmcontext(d, op->cmd);
         if (ret)
@@ -341,7 +376,10 @@ long arch_do_domctl(xen_domctl_t *op, XE
             break;
         }
 
-        ret = domain_opt_feature(d, optf);
+        ret = -EPERM;
+        if ( IS_PRIV_FOR(current->domain, d) )
+            ret = domain_opt_feature(d, optf);
+
         rcu_unlock_domain(d);
     }
     break;
diff -r bcae9d2cc2f8 -r cff4c8a1aa28 xen/arch/ia64/xen/hypercall.c
--- a/xen/arch/ia64/xen/hypercall.c     Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/arch/ia64/xen/hypercall.c     Wed Jan 23 13:21:44 2008 +0000
@@ -500,13 +500,15 @@ do_ia64_debug_op(unsigned long cmd, unsi
     struct domain *d;
     long ret = 0;
 
-    if (!IS_PRIV(current->domain))
-        return -EPERM;
     if (copy_from_guest(op, u_debug_op, 1))
         return -EFAULT;
     d = rcu_lock_domain_by_id(domain);
     if (d == NULL)
         return -ESRCH;
+    if (!IS_PRIV_FOR(current->domain, d)) {
+        ret = -EPERM;
+        goto out;
+    }
 
     switch (cmd) {
     case XEN_IA64_DEBUG_OP_SET_FLAGS:
@@ -520,6 +522,7 @@ do_ia64_debug_op(unsigned long cmd, unsi
     default:
         ret = -ENOSYS;
     }
+out:
     rcu_unlock_domain(d);
     return ret;
 }
diff -r bcae9d2cc2f8 -r cff4c8a1aa28 xen/arch/ia64/xen/mm.c
--- a/xen/arch/ia64/xen/mm.c    Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/arch/ia64/xen/mm.c    Wed Jan 23 13:21:44 2008 +0000
@@ -2787,10 +2787,14 @@ arch_memory_op(int op, XEN_GUEST_HANDLE(
 
         if (xatp.domid == DOMID_SELF)
             d = rcu_lock_current_domain();
-        else if (!IS_PRIV(current->domain))
-            return -EPERM;
-        else if ((d = rcu_lock_domain_by_id(xatp.domid)) == NULL)
-            return -ESRCH;
+        else {
+            if ((d = rcu_lock_domain_by_id(xatp.domid)) == NULL)
+                return -ESRCH;
+            if (!IS_PRIV_FOR(current->domain,d)) {
+                rcu_lock_domain(d);
+                return -EPERM;
+            }
+        }
 
         /* This hypercall is used for VT-i domain only */
         if (!VMX_DOMAIN(d->vcpu[0])) {
diff -r bcae9d2cc2f8 -r cff4c8a1aa28 xen/arch/ia64/xen/xensetup.c
--- a/xen/arch/ia64/xen/xensetup.c      Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/arch/ia64/xen/xensetup.c      Wed Jan 23 13:21:44 2008 +0000
@@ -642,6 +642,7 @@ printk("num_online_cpus=%d, max_cpus=%d\
         panic("Cannot allocate dom0 vcpu 0\n");
 
     dom0->is_privileged = 1;
+    dom0->target = NULL;
 
     /*
      * We're going to setup domain0 using the module(s) that we stashed safely
diff -r bcae9d2cc2f8 -r cff4c8a1aa28 xen/arch/powerpc/setup.c
--- a/xen/arch/powerpc/setup.c  Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/arch/powerpc/setup.c  Wed Jan 23 13:21:44 2008 +0000
@@ -375,6 +375,7 @@ static void __init __start_xen(void)
     dom0->vcpu[0]->cpu_affinity = cpumask_of_cpu(0);
 
     dom0->is_privileged = 1;
+    dom0->target = NULL;
 
     /* scrub_heap_pages() requires IRQs enabled, and we're post IRQ setup... */
     local_irq_enable();
diff -r bcae9d2cc2f8 -r cff4c8a1aa28 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/arch/x86/hvm/hvm.c    Wed Jan 23 13:21:44 2008 +0000
@@ -1740,15 +1740,16 @@ static int hvmop_set_pci_intx_level(
     if ( copy_from_guest(&op, uop, 1) )
         return -EFAULT;
 
-    if ( !IS_PRIV(current->domain) )
-        return -EPERM;
-
     if ( (op.domain > 0) || (op.bus > 0) || (op.device > 31) || (op.intx > 3) )
         return -EINVAL;
 
     d = rcu_lock_domain_by_id(op.domid);
     if ( d == NULL )
         return -ESRCH;
+
+    rc = -EPERM;
+    if ( !IS_PRIV_FOR(current->domain, d) )
+        goto out;
 
     rc = -EINVAL;
     if ( !is_hvm_domain(d) )
@@ -1787,15 +1788,16 @@ static int hvmop_set_isa_irq_level(
     if ( copy_from_guest(&op, uop, 1) )
         return -EFAULT;
 
-    if ( !IS_PRIV(current->domain) )
-        return -EPERM;
-
     if ( op.isa_irq > 15 )
         return -EINVAL;
 
     d = rcu_lock_domain_by_id(op.domid);
     if ( d == NULL )
         return -ESRCH;
+
+    rc = -EPERM;
+    if ( !IS_PRIV_FOR(current->domain, d) )
+        goto out;
 
     rc = -EINVAL;
     if ( !is_hvm_domain(d) )
@@ -1834,15 +1836,16 @@ static int hvmop_set_pci_link_route(
     if ( copy_from_guest(&op, uop, 1) )
         return -EFAULT;
 
-    if ( !IS_PRIV(current->domain) )
-        return -EPERM;
-
     if ( (op.link > 3) || (op.isa_irq > 15) )
         return -EINVAL;
 
     d = rcu_lock_domain_by_id(op.domid);
     if ( d == NULL )
         return -ESRCH;
+
+    rc = -EPERM;
+    if ( !IS_PRIV_FOR(current->domain, d) )
+        goto out;
 
     rc = -EINVAL;
     if ( !is_hvm_domain(d) )
@@ -1921,13 +1924,16 @@ long do_hvm_op(unsigned long op, XEN_GUE
 
         if ( a.domid == DOMID_SELF )
             d = rcu_lock_current_domain();
-        else if ( IS_PRIV(current->domain) )
+        else {
             d = rcu_lock_domain_by_id(a.domid);
-        else
-            return -EPERM;
-
-        if ( d == NULL )
-            return -ESRCH;
+            if ( d == NULL )
+                return -ESRCH;
+            if ( !IS_PRIV_FOR(current->domain, d) ) {
+                rc = -EPERM;
+                goto param_fail;
+            }
+        }
+
 
         rc = -EINVAL;
         if ( !is_hvm_domain(d) )
diff -r bcae9d2cc2f8 -r cff4c8a1aa28 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/arch/x86/mm.c Wed Jan 23 13:21:44 2008 +0000
@@ -2056,38 +2056,35 @@ static int set_foreigndom(domid_t domid)
         MEM_LOG("Cannot mix foreign mappings with translated domains");
         okay = 0;
     }
-    else if ( !IS_PRIV(d) )
-    {
-        switch ( domid )
-        {
-        case DOMID_IO:
-            info->foreign = rcu_lock_domain(dom_io);
-            break;
-        default:
+    else switch ( domid )
+    {
+    case DOMID_IO:
+        info->foreign = rcu_lock_domain(dom_io);
+        break;
+    case DOMID_XEN:
+        if (!IS_PRIV(d)) {
             MEM_LOG("Cannot set foreign dom");
             okay = 0;
             break;
         }
-    }
-    else
-    {
-        info->foreign = e = rcu_lock_domain_by_id(domid);
+        info->foreign = rcu_lock_domain(dom_xen);
+        break;
+    default:
+        e = rcu_lock_domain_by_id(domid);
         if ( e == NULL )
         {
-            switch ( domid )
-            {
-            case DOMID_XEN:
-                info->foreign = rcu_lock_domain(dom_xen);
-                break;
-            case DOMID_IO:
-                info->foreign = rcu_lock_domain(dom_io);
-                break;
-            default:
-                MEM_LOG("Unknown domain '%u'", domid);
-                okay = 0;
-                break;
-            }
-        }
+            MEM_LOG("Unknown domain '%u'", domid);
+            okay = 0;
+            break;
+        }
+        if (!IS_PRIV_FOR(d, e)) {
+            MEM_LOG("Cannot set foreign dom");
+            okay = 0;
+            rcu_unlock_domain(e);
+            break;
+        }
+        info->foreign = e;
+        break;
     }
 
  out:
@@ -3043,9 +3040,6 @@ int do_update_va_mapping_otherdomain(uns
 {
     int rc;
 
-    if ( unlikely(!IS_PRIV(current->domain)) )
-        return -EPERM;
-
     if ( !set_foreigndom(domid) )
         return -ESRCH;
 
@@ -3222,10 +3216,15 @@ long arch_memory_op(int op, XEN_GUEST_HA
 
         if ( xatp.domid == DOMID_SELF )
             d = rcu_lock_current_domain();
-        else if ( !IS_PRIV(current->domain) )
-            return -EPERM;
-        else if ( (d = rcu_lock_domain_by_id(xatp.domid)) == NULL )
-            return -ESRCH;
+        else {
+            d = rcu_lock_domain_by_id(xatp.domid);
+            if ( d == NULL )
+                return -ESRCH;
+            if ( !IS_PRIV_FOR(current->domain, d) ) {
+                rcu_unlock_domain(d);
+                return -EPERM;
+            }
+        }
 
         if ( xsm_add_to_physmap(current->domain, d) )
         {
@@ -3313,10 +3312,15 @@ long arch_memory_op(int op, XEN_GUEST_HA
 
         if ( fmap.domid == DOMID_SELF )
             d = rcu_lock_current_domain();
-        else if ( !IS_PRIV(current->domain) )
-            return -EPERM;
-        else if ( (d = rcu_lock_domain_by_id(fmap.domid)) == NULL )
-            return -ESRCH;
+        else {
+            d = rcu_lock_domain_by_id(fmap.domid);
+            if ( d == NULL )
+                return -ESRCH;
+            if ( !IS_PRIV_FOR(current->domain, d) ) {
+                rcu_unlock_domain(d);
+                return -EPERM;
+            }
+        }
 
         rc = xsm_domain_memory_map(d);
         if ( rc )
diff -r bcae9d2cc2f8 -r cff4c8a1aa28 xen/arch/x86/mm/shadow/multi.c
--- a/xen/arch/x86/mm/shadow/multi.c    Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/arch/x86/mm/shadow/multi.c    Wed Jan 23 13:21:44 2008 +0000
@@ -993,11 +993,11 @@ shadow_get_page_from_l1e(shadow_l1e_t sl
     // not own, we let it succeed anyway.
     //
     if ( unlikely(!res) &&
-         IS_PRIV(d) &&
          !shadow_mode_translate(d) &&
          mfn_valid(mfn = shadow_l1e_get_mfn(sl1e)) &&
          (owner = page_get_owner(mfn_to_page(mfn))) &&
-         (d != owner) )
+         (d != owner) &&
+         IS_PRIV_FOR(d, owner))
     {
         res = get_page_from_l1e(sl1e, owner);
         SHADOW_PRINTK("privileged domain %d installs map of mfn %05lx "
diff -r bcae9d2cc2f8 -r cff4c8a1aa28 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c      Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/arch/x86/setup.c      Wed Jan 23 13:21:44 2008 +0000
@@ -959,6 +959,7 @@ void __init __start_xen(unsigned long mb
         panic("Error creating domain 0\n");
 
     dom0->is_privileged = 1;
+    dom0->target = NULL;
 
     /* Grab the DOM0 command line. */
     cmdline = (char *)(mod[0].string ? __va(mod[0].string) : NULL);
diff -r bcae9d2cc2f8 -r cff4c8a1aa28 xen/common/domain.c
--- a/xen/common/domain.c       Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/common/domain.c       Wed Jan 23 13:21:44 2008 +0000
@@ -502,6 +502,9 @@ static void complete_domain_destroy(stru
         if ( (v = d->vcpu[i]) != NULL )
             free_vcpu_struct(v);
 
+    if (d->target)
+        put_domain(d->target);
+
     free_domain(d);
 
     send_guest_global_virq(dom0, VIRQ_DOM_EXC);
diff -r bcae9d2cc2f8 -r cff4c8a1aa28 xen/common/domctl.c
--- a/xen/common/domctl.c       Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/common/domctl.c       Wed Jan 23 13:21:44 2008 +0000
@@ -182,9 +182,6 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
     struct xen_domctl curop, *op = &curop;
     static DEFINE_SPINLOCK(domctl_lock);
 
-    if ( !IS_PRIV(current->domain) )
-        return -EPERM;
-
     if ( copy_from_guest(op, u_domctl, 1) )
         return -EFAULT;
 
@@ -206,6 +203,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
         ret = -ESRCH;
         if ( d == NULL )
             break;
+
+        ret = -EPERM;
+        if ( !IS_PRIV_FOR(current->domain, d) )
+            goto svc_out;
 
         ret = xsm_setvcpucontext(d);
         if ( ret )
@@ -258,6 +259,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
         ret = -ESRCH;
         if ( d != NULL )
         {
+            ret = -EPERM;
+            if ( !IS_PRIV_FOR(current->domain, d) )
+                goto pausedomain_out;
+
             ret = xsm_pausedomain(d);
             if ( ret )
                 goto pausedomain_out;
@@ -282,16 +287,18 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
         if ( d == NULL )
             break;
 
+        ret = -EPERM;
+        if ( !IS_PRIV_FOR(current->domain, d) )
+            goto unpausedomain_out;
+
         ret = xsm_unpausedomain(d);
         if ( ret )
-        {
-            rcu_unlock_domain(d);
-            break;
-        }
+            goto unpausedomain_out;
 
         domain_unpause_by_systemcontroller(d);
-        rcu_unlock_domain(d);
-        ret = 0;
+        ret = 0;
+unpausedomain_out:
+        rcu_unlock_domain(d);
     }
     break;
 
@@ -303,16 +310,18 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
         if ( d == NULL )
             break;
 
+        ret = -EPERM;
+        if ( !IS_PRIV_FOR(current->domain, d) )
+            goto resumedomain_out;
+
         ret = xsm_resumedomain(d);
         if ( ret )
-        {
-            rcu_unlock_domain(d);
-            break;
-        }
+            goto resumedomain_out;
 
         domain_resume(d);
-        rcu_unlock_domain(d);
-        ret = 0;
+        ret = 0;
+resumedomain_out:
+        rcu_unlock_domain(d);
     }
     break;
 
@@ -322,6 +331,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
         domid_t        dom;
         static domid_t rover = 0;
         unsigned int domcr_flags;
+
+        ret = -EPERM;
+        if ( !IS_PRIV(current->domain) )
+            break;
 
         ret = -EINVAL;
         if ( supervisor_mode_kernel ||
@@ -385,12 +398,13 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
         if ( (d = rcu_lock_domain_by_id(op->domain)) == NULL )
             break;
 
+        ret = -EPERM;
+        if ( !IS_PRIV_FOR(current->domain, d) )
+            goto maxvcpu_out2;
+
         ret = xsm_max_vcpus(d);
         if ( ret )
-        {
-            rcu_unlock_domain(d);
-            break;
-        }
+            goto maxvcpu_out2;
 
         /* Needed, for example, to ensure writable p.t. state is synced. */
         domain_pause(d);
@@ -418,6 +432,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
 
     maxvcpu_out:
         domain_unpause(d);
+    maxvcpu_out2:
         rcu_unlock_domain(d);
     }
     break;
@@ -428,7 +443,9 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
         ret = -ESRCH;
         if ( d != NULL )
         {
-            ret = xsm_destroydomain(d) ? : domain_kill(d);
+            ret = -EPERM;
+            if ( IS_PRIV_FOR(current->domain, d) )
+                ret = xsm_destroydomain(d) ? : domain_kill(d);
             rcu_unlock_domain(d);
         }
     }
@@ -446,6 +463,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
         if ( d == NULL )
             break;
 
+        ret = -EPERM;
+        if ( !IS_PRIV_FOR(current->domain, d) )
+            goto vcpuaffinity_out;
+
         ret = xsm_vcpuaffinity(op->cmd, d);
         if ( ret )
             goto vcpuaffinity_out;
@@ -484,6 +505,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
         if ( (d = rcu_lock_domain_by_id(op->domain)) == NULL )
             break;
 
+        ret = -EPERM;
+        if ( !IS_PRIV_FOR(current->domain, d) )
+            goto scheduler_op_out;
+
         ret = xsm_scheduler(d);
         if ( ret )
             goto scheduler_op_out;
@@ -505,7 +530,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
         rcu_read_lock(&domlist_read_lock);
 
         for_each_domain ( d )
-            if ( d->domain_id >= dom )
+            if ( d->domain_id >= dom && IS_PRIV_FOR(current->domain, d))
                 break;
 
         if ( d == NULL )
@@ -539,6 +564,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
         ret = -ESRCH;
         if ( (d = rcu_lock_domain_by_id(op->domain)) == NULL )
             break;
+
+        ret = -EPERM;
+        if ( !IS_PRIV_FOR(current->domain, d) )
+            goto getvcpucontext_out;
 
         ret = xsm_getvcpucontext(d);
         if ( ret )
@@ -600,6 +629,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
         if ( (d = rcu_lock_domain_by_id(op->domain)) == NULL )
             break;
 
+        ret = -EPERM;
+        if ( !IS_PRIV_FOR(current->domain, d) )
+            goto getvcpuinfo_out;
+
         ret = xsm_getvcpuinfo(d);
         if ( ret )
             goto getvcpuinfo_out;
@@ -639,6 +672,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
         if ( d == NULL )
             break;
 
+        ret = -EPERM;
+        if ( !IS_PRIV_FOR(current->domain, d) )
+            goto max_mem_out;
+
         ret = xsm_setdomainmaxmem(d);
         if ( ret )
             goto max_mem_out;
@@ -655,6 +692,8 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
             d->max_pages = new_max;
             ret = 0;
         }
+        else
+            printk("new max %ld, tot pages %d\n", new_max, d->tot_pages);
         spin_unlock(&d->page_alloc_lock);
 
     max_mem_out:
@@ -671,17 +710,19 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
         if ( d == NULL )
             break;
 
+        ret = -EPERM;
+        if ( !IS_PRIV_FOR(current->domain, d) )
+            goto setdomainhandle_out;
+
         ret = xsm_setdomainhandle(d);
         if ( ret )
-        {
-            rcu_unlock_domain(d);
-            break;
-        }
+            goto setdomainhandle_out;
 
         memcpy(d->handle, op->u.setdomainhandle.handle,
                sizeof(xen_domain_handle_t));
-        rcu_unlock_domain(d);
-        ret = 0;
+        ret = 0;
+setdomainhandle_out:
+        rcu_unlock_domain(d);
     }
     break;
 
@@ -694,18 +735,20 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
         if ( d == NULL )
             break;
 
+        ret = -EPERM;
+        if ( !IS_PRIV_FOR(current->domain, d) )
+            goto setdebugging_out;
+
         ret = xsm_setdebugging(d);
         if ( ret )
-        {
-            rcu_unlock_domain(d);
-            break;
-        }
+            goto setdebugging_out;
 
         domain_pause(d);
         d->debugger_attached = !!op->u.setdebugging.enable;
         domain_unpause(d); /* causes guest to latch new status */
-        rcu_unlock_domain(d);
-        ret = 0;
+        ret = 0;
+setdebugging_out:
+        rcu_unlock_domain(d);
     }
     break;
 
@@ -722,6 +765,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
         d = rcu_lock_domain_by_id(op->domain);
         if ( d == NULL )
             break;
+
+        ret = -EPERM;
+        if ( !IS_PRIV_FOR(current->domain, d) )
+            goto irq_permission_out;
 
         ret = xsm_irq_permission(d, pirq, op->u.irq_permission.allow_access);
         if ( ret )
@@ -752,6 +799,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
         if ( d == NULL )
             break;
 
+        ret = -EPERM;
+        if ( !IS_PRIV_FOR(current->domain, d) )
+            goto iomem_permission_out;
+
         ret = xsm_iomem_permission(d, mfn, 
op->u.iomem_permission.allow_access);
         if ( ret )
             goto iomem_permission_out;
@@ -772,19 +823,61 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
 
         ret = -ESRCH;
         d = rcu_lock_domain_by_id(op->domain);
-        if ( d != NULL )
-        {
-            ret = xsm_domain_settime(d);
-            if ( ret )
-            {
-                rcu_unlock_domain(d);
-                break;
-            }
-
-            d->time_offset_seconds = op->u.settimeoffset.time_offset_seconds;
-            rcu_unlock_domain(d);
-            ret = 0;
-        }
+        if ( d == NULL )
+            break;
+
+        ret = -EPERM;
+        if ( !IS_PRIV_FOR(current->domain, d) )
+            goto settimeoffset_out;
+
+        ret = xsm_domain_settime(d);
+        if ( ret )
+            goto settimeoffset_out;
+
+        d->time_offset_seconds = op->u.settimeoffset.time_offset_seconds;
+
+        ret = 0;
+settimeoffset_out:
+        rcu_unlock_domain(d);
+    }
+    break;
+
+    case XEN_DOMCTL_set_target:
+    {
+        struct domain *d, *e;
+
+        ret = -ESRCH;
+        d = rcu_lock_domain_by_id(op->domain);
+        if ( d == NULL )
+            break;
+
+        ret = -EPERM;
+        if (!IS_PRIV_FOR(current->domain, d))
+            goto set_target_out;
+
+        ret = -ESRCH;
+        e = get_domain_by_id(op->u.set_target.target);
+        if ( e == NULL )
+            goto set_target_out;
+
+        if ( d == e ) {
+            ret = -EINVAL;
+            put_domain(e);
+            goto set_target_out;
+        }
+
+        if (!IS_PRIV_FOR(current->domain, e)) {
+            ret = -EPERM;
+            put_domain(e);
+            goto set_target_out;
+        }
+
+        d->target = e;
+        /* and we keep the reference on e, released when destroying d */
+        ret = 0;
+
+set_target_out:
+        rcu_unlock_domain(d);
     }
     break;
 
diff -r bcae9d2cc2f8 -r cff4c8a1aa28 xen/common/event_channel.c
--- a/xen/common/event_channel.c        Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/common/event_channel.c        Wed Jan 23 13:21:44 2008 +0000
@@ -130,12 +130,15 @@ static long evtchn_alloc_unbound(evtchn_
     long           rc;
 
     if ( dom == DOMID_SELF )
-        dom = current->domain->domain_id;
-    else if ( !IS_PRIV(current->domain) )
-        return -EPERM;
-
-    if ( (d = rcu_lock_domain_by_id(dom)) == NULL )
-        return -ESRCH;
+        d = current->domain;
+    else {
+        if ( (d = rcu_lock_domain_by_id(dom)) == NULL )
+            return -ESRCH;
+        if ( !IS_PRIV_FOR(current->domain, d) ) {
+            rc = -EPERM;
+            goto out2;
+        }
+    }
 
     spin_lock(&d->evtchn_lock);
 
@@ -156,6 +159,7 @@ static long evtchn_alloc_unbound(evtchn_
  out:
     spin_unlock(&d->evtchn_lock);
 
+ out2:
     rcu_unlock_domain(d);
 
     return rc;
@@ -197,7 +201,7 @@ static long evtchn_bind_interdomain(evtc
         ERROR_EXIT_DOM(-EINVAL, rd);
     rchn = evtchn_from_port(rd, rport);
     if ( (rchn->state != ECS_UNBOUND) ||
-         (rchn->u.unbound.remote_domid != ld->domain_id) )
+            (rchn->u.unbound.remote_domid != ld->domain_id && !IS_PRIV_FOR(ld, 
rd)))
         ERROR_EXIT_DOM(-EINVAL, rd);
 
     rc = xsm_evtchn_interdomain(ld, lchn, rd, rchn);
@@ -628,12 +632,15 @@ static long evtchn_status(evtchn_status_
     long             rc = 0;
 
     if ( dom == DOMID_SELF )
-        dom = current->domain->domain_id;
-    else if ( !IS_PRIV(current->domain) )
-        return -EPERM;
-
-    if ( (d = rcu_lock_domain_by_id(dom)) == NULL )
-        return -ESRCH;
+        d = current->domain;
+    else {
+        if ( (d = rcu_lock_domain_by_id(dom)) == NULL )
+            return -ESRCH;
+        if ( !IS_PRIV_FOR(current->domain, d) ) {
+            rc = -EPERM;
+            goto out2;
+        }
+    }
 
     spin_lock(&d->evtchn_lock);
 
@@ -684,6 +691,7 @@ static long evtchn_status(evtchn_status_
 
  out:
     spin_unlock(&d->evtchn_lock);
+ out2:
     rcu_unlock_domain(d);
     return rc;
 }
@@ -782,26 +790,28 @@ static long evtchn_reset(evtchn_reset_t 
     int rc;
 
     if ( dom == DOMID_SELF )
-        dom = current->domain->domain_id;
-    else if ( !IS_PRIV(current->domain) )
-        return -EPERM;
-
-    if ( (d = rcu_lock_domain_by_id(dom)) == NULL )
-        return -ESRCH;
+        d = current->domain;
+    else {
+        if ( (d = rcu_lock_domain_by_id(dom)) == NULL )
+            return -ESRCH;
+        if ( !IS_PRIV_FOR(current->domain, d) ) {
+            rc = -EPERM;
+            goto out;
+        }
+    }
 
     rc = xsm_evtchn_reset(current->domain, d);
     if ( rc )
-    {
-        rcu_unlock_domain(d);
-        return rc;
-    }
+        goto out;
 
     for ( i = 0; port_is_valid(d, i); i++ )
         (void)__evtchn_close(d, i);
 
+    rc = 0;
+out:
     rcu_unlock_domain(d);
 
-    return 0;
+    return rc;
 }
 
 
diff -r bcae9d2cc2f8 -r cff4c8a1aa28 xen/common/grant_table.c
--- a/xen/common/grant_table.c  Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/common/grant_table.c  Wed Jan 23 13:21:44 2008 +0000
@@ -834,19 +834,19 @@ gnttab_setup_table(
     dom = op.dom;
     if ( dom == DOMID_SELF )
     {
-        dom = current->domain->domain_id;
-    }
-    else if ( unlikely(!IS_PRIV(current->domain)) )
-    {
-        op.status = GNTST_permission_denied;
-        goto out;
-    }
-
-    if ( unlikely((d = rcu_lock_domain_by_id(dom)) == NULL) )
-    {
-        gdprintk(XENLOG_INFO, "Bad domid %d.\n", dom);
-        op.status = GNTST_bad_domain;
-        goto out;
+        d = current->domain;
+    }
+    else {
+        if ( unlikely((d = rcu_lock_domain_by_id(dom)) == NULL) )
+        {
+            gdprintk(XENLOG_INFO, "Bad domid %d.\n", dom);
+            op.status = GNTST_bad_domain;
+            goto out;
+        }
+        if ( unlikely(!IS_PRIV_FOR(current->domain, d)) ) {
+            op.status = GNTST_permission_denied;
+            goto setup_unlock_out2;
+        }
     }
 
     if ( xsm_grant_setup(current->domain, d) )
@@ -880,6 +880,7 @@ gnttab_setup_table(
  setup_unlock_out:
     spin_unlock(&d->grant_table->lock);
 
+ setup_unlock_out2:
     rcu_unlock_domain(d);
 
  out:
@@ -910,27 +911,26 @@ gnttab_query_size(
     dom = op.dom;
     if ( dom == DOMID_SELF )
     {
-        dom = current->domain->domain_id;
-    }
-    else if ( unlikely(!IS_PRIV(current->domain)) )
-    {
-        op.status = GNTST_permission_denied;
-        goto query_out;
-    }
-
-    if ( unlikely((d = rcu_lock_domain_by_id(dom)) == NULL) )
-    {
-        gdprintk(XENLOG_INFO, "Bad domid %d.\n", dom);
-        op.status = GNTST_bad_domain;
-        goto query_out;
+        d = current->domain;
+    }
+    else {
+        if ( unlikely((d = rcu_lock_domain_by_id(dom)) == NULL) )
+        {
+            gdprintk(XENLOG_INFO, "Bad domid %d.\n", dom);
+            op.status = GNTST_bad_domain;
+            goto query_out;
+        }
+        if ( unlikely(!IS_PRIV_FOR(current->domain, d)) ) {
+            op.status = GNTST_permission_denied;
+            goto query_out_unlock;
+        }
     }
 
     rc = xsm_grant_query_size(current->domain, d);
     if ( rc )
     {
-        rcu_unlock_domain(d);
         op.status = GNTST_permission_denied;
-        goto query_out;
+        goto query_out_unlock;
     }
 
     spin_lock(&d->grant_table->lock);
@@ -941,6 +941,8 @@ gnttab_query_size(
 
     spin_unlock(&d->grant_table->lock);
 
+ 
+ query_out_unlock:
     rcu_unlock_domain(d);
 
  query_out:
diff -r bcae9d2cc2f8 -r cff4c8a1aa28 xen/common/memory.c
--- a/xen/common/memory.c       Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/common/memory.c       Wed Jan 23 13:21:44 2008 +0000
@@ -232,12 +232,17 @@ static long translate_gpfn_list(
         return -EFAULT;
 
     if ( op.domid == DOMID_SELF )
-        op.domid = current->domain->domain_id;
-    else if ( !IS_PRIV(current->domain) )
-        return -EPERM;
-
-    if ( (d = rcu_lock_domain_by_id(op.domid)) == NULL )
-        return -ESRCH;
+        d = current->domain;
+    else {
+        d = rcu_lock_domain_by_id(op.domid);
+        if ( d == NULL )
+            return -ESRCH;
+        if ( !IS_PRIV_FOR(current->domain, d) ) {
+            rcu_unlock_domain(d);
+            return -EPERM;
+        }
+    }
+
 
     if ( !paging_mode_translate(d) )
     {
@@ -535,9 +540,15 @@ long do_memory_op(unsigned long cmd, XEN
 
         if ( likely(reservation.domid == DOMID_SELF) )
             d = current->domain;
-        else if ( !IS_PRIV(current->domain) ||
-                  ((d = rcu_lock_domain_by_id(reservation.domid)) == NULL) )
-            return start_extent;
+        else {
+            d = rcu_lock_domain_by_id(reservation.domid);
+            if ( d == NULL)
+                return start_extent;
+            if ( !IS_PRIV_FOR(current->domain, d) ) {
+                rcu_unlock_domain(d);
+                return start_extent;
+            }
+        }
         args.domain = d;
 
         rc = xsm_memory_adjust_reservation(current->domain, d);
@@ -589,10 +600,15 @@ long do_memory_op(unsigned long cmd, XEN
 
         if ( likely(domid == DOMID_SELF) )
             d = current->domain;
-        else if ( !IS_PRIV(current->domain) )
-            return -EPERM;
-        else if ( (d = rcu_lock_domain_by_id(domid)) == NULL )
-            return -ESRCH;
+        else {
+            d = rcu_lock_domain_by_id(domid);
+            if ( d == NULL )
+                return -ESRCH;
+            if ( !IS_PRIV_FOR(current->domain, d) ) {
+                rcu_unlock_domain(d);
+                return -EPERM;
+            }
+        }
 
         rc = xsm_memory_stat_reservation(current->domain, d);
         if ( rc )
diff -r bcae9d2cc2f8 -r cff4c8a1aa28 xen/common/schedule.c
--- a/xen/common/schedule.c     Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/common/schedule.c     Wed Jan 23 13:21:44 2008 +0000
@@ -461,9 +461,6 @@ ret_t do_sched_op(int cmd, XEN_GUEST_HAN
         struct domain *d;
         struct sched_remote_shutdown sched_remote_shutdown;
 
-        if ( !IS_PRIV(current->domain) )
-            return -EPERM;
-
         ret = -EFAULT;
         if ( copy_from_guest(&sched_remote_shutdown, arg, 1) )
             break;
@@ -472,6 +469,12 @@ ret_t do_sched_op(int cmd, XEN_GUEST_HAN
         d = rcu_lock_domain_by_id(sched_remote_shutdown.domain_id);
         if ( d == NULL )
             break;
+
+        if ( !IS_PRIV_FOR(current->domain, d) )
+        {
+            rcu_unlock_domain(d);
+            return -EPERM;
+        }
 
         ret = xsm_schedop_shutdown(current->domain, d);
         if ( ret )
diff -r bcae9d2cc2f8 -r cff4c8a1aa28 xen/include/public/domctl.h
--- a/xen/include/public/domctl.h       Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/include/public/domctl.h       Wed Jan 23 13:21:44 2008 +0000
@@ -554,6 +554,17 @@ typedef struct xen_domctl_set_opt_featur
 typedef struct xen_domctl_set_opt_feature xen_domctl_set_opt_feature_t;
 DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_opt_feature_t);
 
+/*
+ * Set the target domain for a domain
+ */
+#define XEN_DOMCTL_set_target    46
+struct xen_domctl_set_target {
+    domid_t target;
+};
+typedef struct xen_domctl_set_target xen_domctl_set_target_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_target_t);
+
+
 struct xen_domctl {
     uint32_t cmd;
     uint32_t interface_version; /* XEN_DOMCTL_INTERFACE_VERSION */
@@ -590,6 +601,7 @@ struct xen_domctl {
         struct xen_domctl_pin_mem_cacheattr pin_mem_cacheattr;
         struct xen_domctl_ext_vcpucontext   ext_vcpucontext;
         struct xen_domctl_set_opt_feature   set_opt_feature;
+        struct xen_domctl_set_target        set_target;
         uint8_t                             pad[128];
     } u;
 };
diff -r bcae9d2cc2f8 -r cff4c8a1aa28 xen/include/xen/sched.h
--- a/xen/include/xen/sched.h   Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/include/xen/sched.h   Wed Jan 23 13:21:44 2008 +0000
@@ -187,6 +187,8 @@ struct domain
     bool_t           is_hvm;
     /* Is this guest fully privileged (aka dom0)? */
     bool_t           is_privileged;
+    /* Which guest this guest has privileges on */
+    struct domain   *target;
     /* Is this guest being debugged by dom0? */
     bool_t           debugger_attached;
     /* Are any VCPUs polling event channels (SCHEDOP_poll)? */
@@ -493,6 +495,7 @@ static inline void vcpu_unblock(struct v
 }
 
 #define IS_PRIV(_d) ((_d)->is_privileged)
+#define IS_PRIV_FOR(_d, _t) (IS_PRIV(_d) || ((_d)->target && (_d)->target == 
(_t)))
 
 #ifndef IS_COMPAT
 #define IS_COMPAT(d) 0
diff -r bcae9d2cc2f8 -r cff4c8a1aa28 
xen/xsm/acm/acm_simple_type_enforcement_hooks.c
--- a/xen/xsm/acm/acm_simple_type_enforcement_hooks.c   Wed Jan 23 11:21:35 
2008 +0000
+++ b/xen/xsm/acm/acm_simple_type_enforcement_hooks.c   Wed Jan 23 13:21:44 
2008 +0000
@@ -817,17 +817,19 @@ ste_pre_grant_setup (domid_t id)
         return ACM_ACCESS_PERMITTED;
     }
     atomic_inc(&ste_bin_pol.gt_eval_count);
+    subj = current->domain;
+    obj = rcu_lock_domain_by_id(id);
+
     /* a) check authorization (eventually use specific capabilities) */
-    if ( !IS_PRIV(current->domain) )
+    if ( obj && !IS_PRIV_FOR(current->domain, obj) )
     {
         printk("%s: Grant table management authorization denied ERROR!\n",
                __func__);
+        rcu_unlock_domain(obj);
         return ACM_ACCESS_DENIED;
     }
+
     /* b) check types */
-    subj = current->domain;
-    obj = rcu_lock_domain_by_id(id);
-
     if ( share_common_type(subj, obj) )
     {
         cache_result(subj, obj);

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] New XEN_DOMCTL_set_target, Xen patchbot-unstable <=