# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1210583352 -3600
# Node ID e3be00bd6aa963aca563692c271af762f9380ba0
# Parent 4afc6023e8eca87590d7d6e89bebad45f299235c
ioemu: fix disk format security vulnerability
* make the xenstore reader in qemu-dm's startup determine which
of qemu's block drivers to use according to the xenstore
backend `type' field. This `type' field typically comes from
the front of the drive mapping string in ioemu. The
supported cases are:
xm config file string `type' image format qemu driver
phy:[/dev/]<device> phy raw image bdrv_raw
file:<filename> file raw image bdrv_raw
tap:aio:<filename> tap raw image bdrv_raw
tap:qcow:<image> tap not raw autoprobe
tap:<cow-fmt>:<image> tap named format bdrv_<cow-fmt>
It is still necessary to autoprobe when the image is specified as
`tap:qcow:<image>', because qemu distinguishes `qcow' and `qcow2'
whereas blktap doesn't; `qcow' in xenstore typically means what
qemu calls qcow2. This is OK because qemu can safely distinguish
the different cow formats provided we know it's not a raw image.
* Make the format autoprobing machinery never return `raw'. This has
two purposes: firstly, it arranges that the `tap:qcow:...' case
above can be handled without accidentally falling back to raw
format. Secondly it prevents accidents in case the code changes in
future: autoprobing will now always fail on supposed cow files which
actually contain junk, rather than giving the guest access to the
underlying file.
Signed-off-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
---
tools/ioemu/block.c | 2 +-
tools/ioemu/xenstore.c | 36 ++++++++++++++++++++++++++++++++----
2 files changed, 33 insertions(+), 5 deletions(-)
diff -r 4afc6023e8ec -r e3be00bd6aa9 tools/ioemu/block.c
--- a/tools/ioemu/block.c Mon May 12 10:07:26 2008 +0100
+++ b/tools/ioemu/block.c Mon May 12 10:09:12 2008 +0100
@@ -254,7 +254,7 @@ static BlockDriver *find_protocol(const
#endif
p = strchr(filename, ':');
if (!p)
- return &bdrv_raw;
+ return NULL; /* do not ever guess raw, it is a security problem! */
len = p - filename;
if (len > sizeof(protocol) - 1)
len = sizeof(protocol) - 1;
diff -r 4afc6023e8ec -r e3be00bd6aa9 tools/ioemu/xenstore.c
--- a/tools/ioemu/xenstore.c Mon May 12 10:07:26 2008 +0100
+++ b/tools/ioemu/xenstore.c Mon May 12 10:09:12 2008 +0100
@@ -90,6 +90,7 @@ void xenstore_parse_domain_config(int hv
int i, is_scsi, is_hdN = 0;
unsigned int len, num, hd_index, pci_devid = 0;
BlockDriverState *bs;
+ BlockDriver *format;
for(i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++)
media_filename[i] = NULL;
@@ -135,6 +136,8 @@ void xenstore_parse_domain_config(int hv
}
for (i = 0; i < num; i++) {
+ format = NULL; /* don't know what the format is yet */
+
/* read the backend path */
if (pasprintf(&buf, "%s/device/vbd/%s/backend", path, e[i]) == -1)
continue;
@@ -181,13 +184,20 @@ void xenstore_parse_domain_config(int hv
drv = xs_read(xsh, XBT_NULL, buf, &len);
if (drv == NULL)
continue;
- /* Strip off blktap sub-type prefix aio: - QEMU can autodetect this */
+ /* Obtain blktap sub-type prefix */
if (!strcmp(drv, "tap") && params[0]) {
char *offset = strchr(params, ':');
if (!offset)
continue ;
+ free(drv);
+ drv = malloc(offset - params + 1);
+ memcpy(drv, params, offset - params);
+ drv[offset - params] = '\0';
+ if (!strcmp(drv, "aio"))
+ /* qemu does aio anyway if it can */
+ format = &bdrv_raw;
memmove(params, offset+1, strlen(offset+1)+1 );
- fprintf(logfile, "Strip off blktap sub-type prefix to %s\n",
params);
+ fprintf(logfile, "Strip off blktap sub-type prefix to %s (drv
'%s')\n", params, drv);
}
/* Prefix with /dev/ if needed */
if (!strcmp(drv, "phy") && params[0] != '/') {
@@ -195,6 +205,7 @@ void xenstore_parse_domain_config(int hv
sprintf(newparams, "/dev/%s", params);
free(params);
params = newparams;
+ format = &bdrv_raw;
}
/*
@@ -240,8 +251,25 @@ void xenstore_parse_domain_config(int hv
#endif
if (params[0]) {
- if (bdrv_open(bs, params, 0 /* snapshot */) < 0)
- fprintf(stderr, "qemu: could not open vbd '%s' or hard disk
image '%s'\n", buf, params);
+ if (!format) {
+ if (!drv) {
+ fprintf(stderr, "qemu: type (image format) not specified
for vbd '%s' or image '%s'\n", buf, params);
+ continue;
+ }
+ if (!strcmp(drv,"qcow")) {
+ /* autoguess qcow vs qcow2 */
+ } else if (!strcmp(drv,"file")) {
+ format = &bdrv_raw;
+ } else {
+ format = bdrv_find_format(drv);
+ if (!format) {
+ fprintf(stderr, "qemu: type (image format) '%s' unknown
for vbd '%s' or image '%s'\n", drv, buf, params);
+ continue;
+ }
+ }
+ }
+ if (bdrv_open2(bs, params, 0 /* snapshot */, format) < 0)
+ fprintf(stderr, "qemu: could not open vbd '%s' or hard disk
image '%s' (drv '%s')\n", buf, params, drv ? drv : "?");
}
}
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|