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-devel

[Xen-devel] [PATCH] New XEN_DOMCTL_set_target and IS_PRIV_FOR

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH] New XEN_DOMCTL_set_target and IS_PRIV_FOR
From: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>
Date: Wed, 23 Jan 2008 11:55:29 +0000
Delivery-date: Wed, 23 Jan 2008 03:56:43 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Mail-followup-to: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.5.12-2006-07-14
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>

diff -r bcae9d2cc2f8 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 11:36:15 2008 +0000
@@ -875,6 +875,20 @@
     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
--- a/tools/libxc/xenctrl.h     Wed Jan 23 11:21:35 2008 +0000
+++ b/tools/libxc/xenctrl.h     Wed Jan 23 11:36:15 2008 +0000
@@ -952,4 +952,9 @@
                               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 */
--- 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 11:36:15 2008 +0000
@@ -96,17 +96,17 @@
                                     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 };
+    static char *kwd_list[] = { "domid", "ssidref", "handle", "hvm", "target", 
NULL };
 
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiOi", kwd_list,
-                                      &dom, &ssidref, &pyhandle, &hvm))
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiOii", kwd_list,
+                                     &dom, &ssidref, &pyhandle, &hvm, &target))
         return NULL;
 
     if ( pyhandle != NULL )
@@ -130,6 +130,11 @@
     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);
 
--- 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 11:36:15 2008 +0000
@@ -170,6 +170,7 @@
     'platform': dict,
     'tools_version': dict,
     'other_config': dict,
+    'target': int,
     'security_label': str,
     'pci': str,
 }
@@ -336,7 +337,8 @@
             'vbd_refs': [],
             'vtpm_refs': [],
             'other_config': {},
-            'platform': {}
+            'platform': {},
+            'target': 0,
         }
         
         return defaults
@@ -1585,6 +1587,9 @@
     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')
--- 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 11:36:15 2008 +0000
@@ -1640,7 +1640,8 @@
                 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():
--- 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 11:36:15 2008 +0000
@@ -521,6 +521,10 @@
           - 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 @@
     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])
--- 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 11:36:15 2008 +0000
@@ -47,15 +47,16 @@
     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 @@
     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 @@
         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;
--- 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 11:36:15 2008 +0000
@@ -37,9 +37,6 @@
 {
     long ret = 0;
 
-    if ( !IS_PRIV(current->domain) )
-        return -EPERM;
-
     switch ( op->cmd )
     {
     case XEN_DOMCTL_getmemlist:
@@ -54,6 +51,13 @@
             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 @@
 
         if ( d == NULL) {
             ret = -EINVAL;
+            break;
+        }
+
+        if ( !IS_PRIV_FOR(current->domain, d) ) {
+            ret = -EPERM;
+            rcu_unlock_domain(d);
             break;
         }
 
@@ -153,6 +163,12 @@
         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 @@
         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 @@
         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 @@
         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)
@@ -279,6 +310,10 @@
         d = rcu_lock_domain_by_id(op->domain);
         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);
@@ -341,7 +376,10 @@
             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;
--- 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 11:36:15 2008 +0000
@@ -500,13 +500,15 @@
     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 @@
     default:
         ret = -ENOSYS;
     }
+out:
     rcu_unlock_domain(d);
     return ret;
 }
--- 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 11:36:15 2008 +0000
@@ -2787,10 +2787,14 @@
 
         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])) {
--- 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 11:36:15 2008 +0000
@@ -642,6 +642,7 @@
         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
--- a/xen/arch/powerpc/setup.c  Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/arch/powerpc/setup.c  Wed Jan 23 11:36:15 2008 +0000
@@ -375,6 +375,7 @@
     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();
--- 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 11:36:15 2008 +0000
@@ -1740,15 +1740,16 @@
     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 @@
     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 @@
     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 @@
 
         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 ( !IS_PRIV_FOR(current->domain, d) ) {
+                rc = -EPERM;
+                goto param_fail;
+            }
+        }
 
-        if ( d == NULL )
-            return -ESRCH;
 
         rc = -EINVAL;
         if ( !is_hvm_domain(d) )
--- a/xen/arch/x86/mm.c Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/arch/x86/mm.c Wed Jan 23 11:36:15 2008 +0000
@@ -2056,38 +2056,35 @@
         MEM_LOG("Cannot mix foreign mappings with translated domains");
         okay = 0;
     }
-    else if ( !IS_PRIV(d) )
+    else switch ( domid )
     {
-        switch ( domid )
-        {
-        case DOMID_IO:
-            info->foreign = rcu_lock_domain(dom_io);
-            break;
-        default:
+    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 rc;
 
-    if ( unlikely(!IS_PRIV(current->domain)) )
-        return -EPERM;
-
     if ( !set_foreigndom(domid) )
         return -ESRCH;
 
@@ -3222,10 +3216,15 @@
 
         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 @@
 
         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 )
--- 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 11:36:15 2008 +0000
@@ -993,11 +993,11 @@
     // 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 "
--- a/xen/arch/x86/setup.c      Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/arch/x86/setup.c      Wed Jan 23 11:36:15 2008 +0000
@@ -959,6 +959,7 @@
         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);
--- a/xen/common/domain.c       Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/common/domain.c       Wed Jan 23 11:36:15 2008 +0000
@@ -502,6 +502,9 @@
         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);
--- a/xen/common/domctl.c       Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/common/domctl.c       Wed Jan 23 11:36:15 2008 +0000
@@ -182,9 +182,6 @@
     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 @@
         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 @@
         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 @@
         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);
+        ret = 0;
+unpausedomain_out:
         rcu_unlock_domain(d);
-        ret = 0;
     }
     break;
 
@@ -303,16 +310,18 @@
         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);
+        ret = 0;
+resumedomain_out:
         rcu_unlock_domain(d);
-        ret = 0;
     }
     break;
 
@@ -322,6 +331,10 @@
         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 @@
         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 @@
 
     maxvcpu_out:
         domain_unpause(d);
+    maxvcpu_out2:
         rcu_unlock_domain(d);
     }
     break;
@@ -428,7 +443,9 @@
         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);
         }
     }
@@ -445,6 +462,10 @@
         ret = -ESRCH;
         if ( d == NULL )
             break;
+
+        ret = -EPERM;
+        if ( !IS_PRIV_FOR(current->domain, d) )
+            goto vcpuaffinity_out;
 
         ret = xsm_vcpuaffinity(op->cmd, d);
         if ( ret )
@@ -484,6 +505,10 @@
         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 @@
         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 @@
         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 @@
         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 @@
         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 @@
             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 @@
         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));
+        ret = 0;
+setdomainhandle_out:
         rcu_unlock_domain(d);
-        ret = 0;
     }
     break;
 
@@ -694,18 +735,20 @@
         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 */
+        ret = 0;
+setdebugging_out:
         rcu_unlock_domain(d);
-        ret = 0;
     }
     break;
 
@@ -722,6 +765,10 @@
         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 @@
         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 @@
 
         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;
-            }
+        if ( d == NULL )
+            break;
 
-            d->time_offset_seconds = op->u.settimeoffset.time_offset_seconds;
-            rcu_unlock_domain(d);
-            ret = 0;
+        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;
 
--- a/xen/common/event_channel.c        Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/common/event_channel.c        Wed Jan 23 11:36:15 2008 +0000
@@ -130,12 +130,15 @@
     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 @@
  out:
     spin_unlock(&d->evtchn_lock);
 
+ out2:
     rcu_unlock_domain(d);
 
     return rc;
@@ -197,7 +201,7 @@
         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 @@
     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 @@
 
  out:
     spin_unlock(&d->evtchn_lock);
+ out2:
     rcu_unlock_domain(d);
     return rc;
 }
@@ -782,26 +790,28 @@
     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;
 }
 
 
--- a/xen/common/grant_table.c  Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/common/grant_table.c  Wed Jan 23 11:36:15 2008 +0000
@@ -834,19 +834,19 @@
     dom = op.dom;
     if ( dom == DOMID_SELF )
     {
-        dom = current->domain->domain_id;
+        d = current->domain;
     }
-    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;
+    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 @@
  setup_unlock_out:
     spin_unlock(&d->grant_table->lock);
 
+ setup_unlock_out2:
     rcu_unlock_domain(d);
 
  out:
@@ -910,27 +911,26 @@
     dom = op.dom;
     if ( dom == DOMID_SELF )
     {
-        dom = current->domain->domain_id;
+        d = current->domain;
     }
-    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;
+    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 @@
 
     spin_unlock(&d->grant_table->lock);
 
+ 
+ query_out_unlock:
     rcu_unlock_domain(d);
 
  query_out:
--- a/xen/common/memory.c       Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/common/memory.c       Wed Jan 23 11:36:15 2008 +0000
@@ -232,12 +232,17 @@
         return -EFAULT;
 
     if ( op.domid == DOMID_SELF )
-        op.domid = current->domain->domain_id;
-    else if ( !IS_PRIV(current->domain) )
-        return -EPERM;
+        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 ( (d = rcu_lock_domain_by_id(op.domid)) == NULL )
-        return -ESRCH;
 
     if ( !paging_mode_translate(d) )
     {
@@ -535,9 +540,15 @@
 
         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 @@
 
         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 )
--- a/xen/common/schedule.c     Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/common/schedule.c     Wed Jan 23 11:36:15 2008 +0000
@@ -461,9 +461,6 @@
         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 @@
         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 )
--- a/xen/include/public/domctl.h       Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/include/public/domctl.h       Wed Jan 23 11:36:15 2008 +0000
@@ -554,6 +554,17 @@
 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_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;
 };
--- a/xen/include/xen/sched.h   Wed Jan 23 11:21:35 2008 +0000
+++ b/xen/include/xen/sched.h   Wed Jan 23 11:36:15 2008 +0000
@@ -187,6 +187,8 @@
     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 @@
 }
 
 #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
--- 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 11:36:15 
2008 +0000
@@ -817,17 +817,19 @@
         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-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>