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

[Xen-changelog] EVTCHNOP_alloc_unbound can allocate a port in an arbitrary



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID c3d9b7013b1442bcc8890da3b60e8e19688ac1a0
# Parent  6f71824a45c19e860a3655dd8e76a83e047c84d2
EVTCHNOP_alloc_unbound can allocate a port in an arbitrary
domain (only if the caller is sufficiently privileged).

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>

diff -r 6f71824a45c1 -r c3d9b7013b14 
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Wed Oct  5 
17:06:42 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Wed Oct  5 
18:14:13 2005
@@ -485,7 +485,7 @@
 static int setup_blkring(struct xenbus_device *dev, struct blkfront_info *info)
 {
        blkif_sring_t *sring;
-       evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound };
+       evtchn_op_t op;
        int err;
 
        info->ring_ref = GRANT_INVALID_REF;
@@ -508,7 +508,9 @@
        }
        info->ring_ref = err;
 
-       op.u.alloc_unbound.dom = info->backend_id;
+       op.cmd = EVTCHNOP_alloc_unbound;
+       op.u.alloc_unbound.dom = DOMID_SELF;
+       op.u.alloc_unbound.remote_dom = info->backend_id;
        err = HYPERVISOR_event_channel_op(&op);
        if (err) {
                gnttab_end_foreign_access(info->ring_ref, 0);
@@ -518,7 +520,9 @@
                xenbus_dev_error(dev, err, "allocating event channel");
                return err;
        }
+
        blkif_connect(info, op.u.alloc_unbound.port);
+
        return 0;
 }
 
diff -r 6f71824a45c1 -r c3d9b7013b14 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Wed Oct  5 
17:06:42 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Wed Oct  5 
18:14:13 2005
@@ -972,7 +972,7 @@
 
 static int setup_device(struct xenbus_device *dev, struct netfront_info *info)
 {
-       evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound };
+       evtchn_op_t op;
        int err;
 
        info->tx_ring_ref = GRANT_INVALID_REF;
@@ -1010,13 +1010,17 @@
        }
        info->rx_ring_ref = err;
 
-       op.u.alloc_unbound.dom = info->backend_id;
+       op.cmd = EVTCHNOP_alloc_unbound;
+       op.u.alloc_unbound.dom = DOMID_SELF;
+       op.u.alloc_unbound.remote_dom = info->backend_id;
        err = HYPERVISOR_event_channel_op(&op);
        if (err) {
                xenbus_dev_error(dev, err, "allocating event channel");
                goto out;
        }
+
        connect_device(info, op.u.alloc_unbound.port);
+
        return 0;
 
  out:
diff -r 6f71824a45c1 -r c3d9b7013b14 
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c      Wed Oct  5 
17:06:42 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c      Wed Oct  5 
18:14:13 2005
@@ -244,8 +244,7 @@
 {
        tpmif_tx_interface_t *sring;
        struct tpm_private *tp = &my_private;
-
-       evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound };
+       evtchn_op_t op;
        int err;
 
        sring = (void *)__get_free_page(GFP_KERNEL);
@@ -269,7 +268,9 @@
        }
        info->ring_ref = err;
 
-       op.u.alloc_unbound.dom = backend_id;
+       op.cmd = EVTCHNOP_alloc_unbound;
+       op.u.alloc_unbound.dom = DOMID_SELF;
+       op.u.alloc_unbound.remote_dom = backend_id;
        err = HYPERVISOR_event_channel_op(&op);
        if (err) {
                gnttab_end_foreign_access(info->ring_ref, 0);
@@ -278,7 +279,9 @@
                xenbus_dev_error(dev, err, "allocating event channel");
                return err;
        }
+
        tpmif_connect(op.u.alloc_unbound.port, backend_id);
+
        return 0;
 }
 
diff -r 6f71824a45c1 -r c3d9b7013b14 tools/libxc/xc_evtchn.c
--- a/tools/libxc/xc_evtchn.c   Wed Oct  5 17:06:42 2005
+++ b/tools/libxc/xc_evtchn.c   Wed Oct  5 18:14:13 2005
@@ -33,6 +33,7 @@
 
 
 int xc_evtchn_alloc_unbound(int xc_handle,
+                            u32 remote_dom,
                             u32 dom,
                             int *port)
 {
@@ -40,6 +41,7 @@
     int         rc;
 
     op.cmd = EVTCHNOP_alloc_unbound;
+    op.u.alloc_unbound.remote_dom = (domid_t)remote_dom;
     op.u.alloc_unbound.dom  = (domid_t)dom;
     op.u.alloc_unbound.port = (port != NULL) ? *port : 0;
 
diff -r 6f71824a45c1 -r c3d9b7013b14 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Wed Oct  5 17:06:42 2005
+++ b/tools/libxc/xenctrl.h     Wed Oct  5 18:14:13 2005
@@ -306,13 +306,15 @@
  * well-known port within a domain to receive events on.
  *
  * @parm xc_handle a handle to an open hypervisor interface
- * @parm dom the ID of the domain.  This maybe DOMID_SELF
+ * @parm remote_dom the ID of the domain who will later bind
+ * @parm dom the ID of the local domain (the 'allocatee')
  * @parm port a pointer to a port.  This is an in/out parameter.  If *port is
  *            0, then a new port will be assigned, if port is > 0 then that
  *            port is allocated if the port is unallocated.
  * @return 0 on success, -1 on failure
  */
 int xc_evtchn_alloc_unbound(int xc_handle,
+                            u32 remote_dom,
                             u32 dom,
                             int *port);
 
diff -r 6f71824a45c1 -r c3d9b7013b14 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Wed Oct  5 17:06:42 2005
+++ b/tools/python/xen/lowlevel/xc/xc.c Wed Oct  5 18:14:13 2005
@@ -432,16 +432,16 @@
 {
     XcObject *xc = (XcObject *)self;
 
-    u32 dom;
+    u32 dom = DOMID_SELF, remote_dom;
     int port = 0;
 
-    static char *kwd_list[] = { "dom", "port", NULL };
-
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
-                                      &dom, &port) )
-        return NULL;
-
-    if ( xc_evtchn_alloc_unbound(xc->xc_handle, dom, &port) != 0 )
+    static char *kwd_list[] = { "remote_dom", "dom", "port", NULL };
+
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|ii", kwd_list,
+                                      &remote_dom, &dom, &port) )
+        return NULL;
+
+    if ( xc_evtchn_alloc_unbound(xc->xc_handle, remote_dom, dom, &port) != 0 )
         return PyErr_SetFromErrno(xc_error);
 
     return PyInt_FromLong(port);
diff -r 6f71824a45c1 -r c3d9b7013b14 xen/common/event_channel.c
--- a/xen/common/event_channel.c        Wed Oct  5 17:06:42 2005
+++ b/xen/common/event_channel.c        Wed Oct  5 18:14:13 2005
@@ -63,9 +63,18 @@
 static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
 {
     struct evtchn *chn;
-    struct domain *d = current->domain;
+    struct domain *d;
     int            port = alloc->port;
+    domid_t        dom = alloc->dom;
     long           rc = 0;
+
+    if ( dom == DOMID_SELF )
+        dom = current->domain->domain_id;
+    else if ( !IS_PRIV(current->domain) )
+        return -EPERM;
+
+    if ( (d = find_domain_by_id(dom)) == NULL )
+        return -ESRCH;
 
     spin_lock(&d->evtchn_lock);
 
@@ -84,11 +93,11 @@
     {
     case ECS_FREE:
         chn->state = ECS_UNBOUND;
-        chn->u.unbound.remote_domid = alloc->dom;
+        chn->u.unbound.remote_domid = alloc->remote_dom;
         break;
 
     case ECS_UNBOUND:
-        if ( chn->u.unbound.remote_domid != alloc->dom )
+        if ( chn->u.unbound.remote_domid != alloc->remote_dom )
             ERROR_EXIT(-EINVAL);
         break;
 
@@ -99,7 +108,10 @@
  out:
     spin_unlock(&d->evtchn_lock);
 
+    put_domain(d);
+
     alloc->port = port;
+
     return rc;
 }
 
diff -r 6f71824a45c1 -r c3d9b7013b14 xen/include/public/event_channel.h
--- a/xen/include/public/event_channel.h        Wed Oct  5 17:06:42 2005
+++ b/xen/include/public/event_channel.h        Wed Oct  5 18:14:13 2005
@@ -10,14 +10,16 @@
 #define __XEN_PUBLIC_EVENT_CHANNEL_H__
 
 /*
- * EVTCHNOP_alloc_unbound: Prepare a local port for binding to <dom>.
- * <port> may be wildcarded by setting to zero, in which case a fresh port
- * will be allocated, and the field filled in on return.
+ * EVTCHNOP_alloc_unbound: Allocate a port in <dom> for later binding to
+ * <remote_dom>. <port> may be wildcarded by setting to zero, in which case a
+ * fresh port will be allocated, and the field filled in on return.
+ * NOTES:
+ *  1. If the caller is unprivileged then <dom> must be DOMID_SELF.
  */
 #define EVTCHNOP_alloc_unbound    6
 typedef struct evtchn_alloc_unbound {
     /* IN parameters */
-    domid_t dom;
+    domid_t dom, remote_dom;
     /* IN/OUT parameters */
     u32     port;
 } evtchn_alloc_unbound_t;

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


 


Rackspace

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