]> xenbits.xensource.com Git - people/dstodden/blktap.git/commitdiff
CA-40171: Validate vhd parent chain during LV reactivation.
authorDaniel Stodden <daniel.stodden@citrix.com>
Fri, 16 Apr 2010 02:06:04 +0000 (19:06 -0700)
committerDaniel Stodden <daniel.stodden@citrix.com>
Fri, 16 Apr 2010 02:06:04 +0000 (19:06 -0700)
Implementation of tapdisk_vbd_reactivate_volumes follows the vhd
parent chain, but therein lacks a critical check matching child and
parent uuids.

This creates a race window wherein reactivation hits an lv resize on
the master. The new last sector, while unrewritten, may carry garbage
footers. Results may vary, from plain reactivation failures to chain
traversal running off into the weeds.

Fixed with a proper uuid check. Adds some eprintfs to aid debugging
the corner cases.

drivers/tapdisk-vbd.c

index e7b52dce5bdebcf03fb5e382d01137662ce6b2bc..1992de91b7b987f65242fd2f5cfb416a1a30e38d 100644 (file)
@@ -361,6 +361,7 @@ tapdisk_vbd_reactivate_volumes(td_vbd_t *vbd, int resume)
        char *name, *new;
        vhd_context_t vhd;
        vhd_parent_locator_t *loc;
+       uuid_t prt_uuid;
 
        new  = NULL;
        name = NULL;
@@ -388,6 +389,13 @@ tapdisk_vbd_reactivate_volumes(td_vbd_t *vbd, int resume)
 
                for (i = 0; i < TD_VBD_EIO_RETRIES; i++) {
                        err = vhd_open(&vhd, name, VHD_OPEN_RDONLY);
+                       if (!err && cnt > 0) {
+                               err = uuid_compare(vhd.footer.uuid, prt_uuid);
+                               if (err) {
+                                       EPRINTF("child/parent uuid mismatch");
+                                       err = -EINVAL;
+                               }
+                       }
                        if (!err)
                                break;
 
@@ -403,6 +411,8 @@ tapdisk_vbd_reactivate_volumes(td_vbd_t *vbd, int resume)
                        break;
                }
 
+               uuid_copy(prt_uuid, vhd.header.prt_uuid);
+
                loc = NULL;
                for (i = 0; i < 8; i++)
                        if (vhd.header.loc[i].code == PLAT_CODE_MACX) {
@@ -411,6 +421,7 @@ tapdisk_vbd_reactivate_volumes(td_vbd_t *vbd, int resume)
                        }
 
                if (!loc) {
+                       EPRINTF("failed to find parent locator");
                        vhd_close(&vhd);
                        err = -EINVAL;
                        goto fail;
@@ -421,6 +432,7 @@ tapdisk_vbd_reactivate_volumes(td_vbd_t *vbd, int resume)
                vhd_close(&vhd);
 
                if (err) {
+                       EPRINTF("failed to read parent locator");
                        name = NULL;
                        goto fail;
                }