Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/xen/xen In xbdback(4), move the code that copies se...



details:   https://anonhg.NetBSD.org/src/rev/02bb91cd9f74
branches:  trunk
changeset: 765206:02bb91cd9f74
user:      jym <jym%NetBSD.org@localhost>
date:      Sat May 21 15:22:49 2011 +0000

description:
In xbdback(4), move the code that copies segments after the bound checks
of the ``nr_segments'' variable.

In cases where we are running domUs with an architecture different from the
dom0 one (for example: 32 bits domUs on 64 bits dom0), copying segments
with an invalid nr_segments value will lead to the corruption of the
xbdback instance structure and quickly crash the dom0 backend.

Tested under 64 bits dom0 with 32 bits domUs. No regression observed.

ok bouyer@.

Will be pulled up to -4 and -5.

diffstat:

 sys/arch/xen/xen/xbdback_xenbus.c |  41 +++++++++++++++++++++++++++++---------
 1 files changed, 31 insertions(+), 10 deletions(-)

diffs (97 lines):

diff -r 32f3d2f2a770 -r 02bb91cd9f74 sys/arch/xen/xen/xbdback_xenbus.c
--- a/sys/arch/xen/xen/xbdback_xenbus.c Sat May 21 15:10:34 2011 +0000
+++ b/sys/arch/xen/xen/xbdback_xenbus.c Sat May 21 15:22:49 2011 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: xbdback_xenbus.c,v 1.36 2011/05/15 20:58:54 jym Exp $      */
+/*      $NetBSD: xbdback_xenbus.c,v 1.37 2011/05/21 15:22:49 jym Exp $      */
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xbdback_xenbus.c,v 1.36 2011/05/15 20:58:54 jym Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xbdback_xenbus.c,v 1.37 2011/05/21 15:22:49 jym Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -873,7 +873,6 @@
        blkif_request_t *req = &xbdi->xbdi_xen_req;
        blkif_x86_32_request_t *req32;
        blkif_x86_64_request_t *req64;
-       int i;
 
        (void)obj;
        if (xbdi->xbdi_ring.ring_n.req_cons != xbdi->xbdi_req_prod) {
@@ -891,8 +890,6 @@
                        req->handle = req32->handle;
                        req->id = req32->id;
                        req->sector_number = req32->sector_number;
-                       for (i = 0; i < req->nr_segments; i++)
-                               req->seg[i] = req32->seg[i];
                        break;
                            
                case XBDIP_64:
@@ -903,8 +900,6 @@
                        req->handle = req64->handle;
                        req->id = req64->id;
                        req->sector_number = req64->sector_number;
-                       for (i = 0; i < req->nr_segments; i++)
-                               req->seg[i] = req64->seg[i];
                        break;
                }
                XENPRINTF(("xbdback op %d req_cons 0x%x req_prod 0x%x "
@@ -1019,16 +1014,23 @@
 static void *
 xbdback_co_io(struct xbdback_instance *xbdi, void *obj)
 {      
-       int error;
+       int i, error;
+       blkif_request_t *req;
+       blkif_x86_32_request_t *req32;
+       blkif_x86_64_request_t *req64;
 
        (void)obj;
-       if (xbdi->xbdi_xen_req.nr_segments < 1 ||
-           xbdi->xbdi_xen_req.nr_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST ) {
+
+       /* some sanity checks */
+       req = &xbdi->xbdi_xen_req;
+       if (req->nr_segments < 1 ||
+           req->nr_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST) {
                printf("xbdback_io domain %d: %d segments\n",
                       xbdi->xbdi_domid, xbdi->xbdi_xen_req.nr_segments);
                error = EINVAL;
                goto end;
        }
+
        if (xbdi->xbdi_xen_req.operation == BLKIF_OP_WRITE) {
                if (xbdi->xbdi_ro) {
                        error = EROFS;
@@ -1038,6 +1040,25 @@
 
        xbdi->xbdi_segno = 0;
 
+       /* copy request segments */
+       switch(xbdi->xbdi_proto) {
+       case XBDIP_NATIVE:
+               /* already copied in xbdback_co_main_loop */
+               break;
+       case XBDIP_32:
+               req32 = RING_GET_REQUEST(&xbdi->xbdi_ring.ring_32,
+                   xbdi->xbdi_ring.ring_n.req_cons);
+               for (i = 0; i < req->nr_segments; i++)
+                       req->seg[i] = req32->seg[i];
+               break;
+       case XBDIP_64:
+               req64 = RING_GET_REQUEST(&xbdi->xbdi_ring.ring_64,
+                   xbdi->xbdi_ring.ring_n.req_cons);
+               for (i = 0; i < req->nr_segments; i++)
+                       req->seg[i] = req64->seg[i];
+               break;
+       }
+
        xbdi->xbdi_cont = xbdback_co_io_gotreq;
        return xbdback_pool_get(&xbdback_request_pool, xbdi);
  end:



Home | Main Index | Thread Index | Old Index