|
Markus Armbruster |
dfed210 |
It is possible for a guest with a raw formatted disk image to write a
|
|
Markus Armbruster |
dfed210 |
header to that disk image describing another format (such as qcow).
|
|
Markus Armbruster |
dfed210 |
Stopping and subsequent restart of the guest will cause QEMU to detect
|
|
Markus Armbruster |
dfed210 |
that format, and could allow the guest to read any host file.
|
|
Markus Armbruster |
dfed210 |
|
|
Markus Armbruster |
dfed210 |
The patch extends the backend device description in xenstore by an
|
|
Markus Armbruster |
dfed210 |
optional format node. It makes xend force the raw format there,
|
|
Markus Armbruster |
dfed210 |
unless enable-image-format-probing is true in its configuration.
|
|
Markus Armbruster |
dfed210 |
|
|
Markus Armbruster |
dfed210 |
This protects everybody from the vulnerability by default, but breaks
|
|
Markus Armbruster |
dfed210 |
images with formats other than raw. None of our tools creates such
|
|
Markus Armbruster |
dfed210 |
images. People who somehow created them themselves can choose to
|
|
Markus Armbruster |
dfed210 |
switch back to format auto-detection, relinquishing protection.
|
|
Markus Armbruster |
dfed210 |
|
|
Markus Armbruster |
dfed210 |
diff -rup --exclude '*~' a/tools/examples/xend-config.sxp b/tools/examples/xend-config.sxp
|
|
Markus Armbruster |
dfed210 |
--- a/tools/examples/xend-config.sxp 2008-04-22 18:53:55.000000000 +0200
|
|
Markus Armbruster |
dfed210 |
+++ b/tools/examples/xend-config.sxp 2008-05-05 14:19:07.000000000 +0200
|
|
Markus Armbruster |
dfed210 |
@@ -240,3 +240,8 @@
|
|
Markus Armbruster |
dfed210 |
|
|
Markus Armbruster |
dfed210 |
# Script to run when the label of a resource has changed.
|
|
Markus Armbruster |
dfed210 |
#(resource-label-change-script '')
|
|
Markus Armbruster |
dfed210 |
+
|
|
Markus Armbruster |
dfed210 |
+# Allow probing of disk image file format. This is insecure! It lets
|
|
Markus Armbruster |
dfed210 |
+# a malicious domU read any file in dom0. Applies only to fully
|
|
Markus Armbruster |
dfed210 |
+# virtual domUs. Required for using formats other than raw.
|
|
Markus Armbruster |
dfed210 |
+#(enable-image-format-probing no)
|
|
Markus Armbruster |
dfed210 |
diff -rup --exclude '*~' a/tools/ioemu/xenstore.c b/tools/ioemu/xenstore.c
|
|
Markus Armbruster |
dfed210 |
--- a/tools/ioemu/xenstore.c 2008-01-16 19:34:59.000000000 +0100
|
|
Markus Armbruster |
dfed210 |
+++ b/tools/ioemu/xenstore.c 2008-05-05 14:28:34.000000000 +0200
|
|
Markus Armbruster |
dfed210 |
@@ -83,8 +83,10 @@ void xenstore_parse_domain_config(int do
|
|
Markus Armbruster |
dfed210 |
char *buf = NULL, *path;
|
|
Markus Armbruster |
dfed210 |
char *fpath = NULL, *bpath = NULL,
|
|
Markus Armbruster |
dfed210 |
*dev = NULL, *params = NULL, *type = NULL, *drv = NULL;
|
|
Markus Armbruster |
dfed210 |
+ char *format = NULL;
|
|
Markus Armbruster |
dfed210 |
int i, is_scsi, is_hdN = 0;
|
|
Markus Armbruster |
dfed210 |
unsigned int len, num, hd_index;
|
|
Markus Armbruster |
dfed210 |
+ BlockDriver *bdrv;
|
|
Markus Armbruster |
dfed210 |
|
|
Markus Armbruster |
dfed210 |
for(i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++)
|
|
Markus Armbruster |
dfed210 |
media_filename[i] = NULL;
|
|
Markus Armbruster |
dfed210 |
@@ -185,6 +187,19 @@ void xenstore_parse_domain_config(int do
|
|
Markus Armbruster |
dfed210 |
fprintf(logfile, "Strip off blktap sub-type prefix to %s\n", params);
|
|
Markus Armbruster |
dfed210 |
}
|
|
Markus Armbruster |
dfed210 |
|
|
Markus Armbruster |
dfed210 |
+ if (pasprintf(&buf, "%s/format", bpath) == -1)
|
|
Markus Armbruster |
dfed210 |
+ continue;
|
|
Markus Armbruster |
dfed210 |
+ free(format);
|
|
Markus Armbruster |
dfed210 |
+ format = xs_read(xsh, XBT_NULL, buf, &len;;
|
|
Markus Armbruster |
dfed210 |
+ if (format) {
|
|
Markus Armbruster |
dfed210 |
+ bdrv = bdrv_find_format(format);
|
|
Markus Armbruster |
dfed210 |
+ if (!bdrv) {
|
|
Markus Armbruster |
dfed210 |
+ fprintf(logfile, "invalid format '%s' for %s\n", format, bpath);
|
|
Markus Armbruster |
dfed210 |
+ continue;
|
|
Markus Armbruster |
dfed210 |
+ }
|
|
Markus Armbruster |
dfed210 |
+ } else
|
|
Markus Armbruster |
dfed210 |
+ bdrv = NULL;
|
|
Markus Armbruster |
dfed210 |
+
|
|
Markus Armbruster |
dfed210 |
/*
|
|
Markus Armbruster |
dfed210 |
* check if device has a phantom vbd; the phantom is hooked
|
|
Markus Armbruster |
dfed210 |
* to the frontend device (for ease of cleanup), so lookup
|
|
Markus Armbruster |
dfed210 |
@@ -218,8 +233,8 @@ void xenstore_parse_domain_config(int do
|
|
Markus Armbruster |
dfed210 |
}
|
|
Markus Armbruster |
dfed210 |
/* open device now if media present */
|
|
Markus Armbruster |
dfed210 |
if (params[0]) {
|
|
Markus Armbruster |
dfed210 |
- if (bdrv_open(bs_table[hd_index + (is_scsi ? MAX_DISKS : 0)],
|
|
Markus Armbruster |
dfed210 |
- params, 0 /* snapshot */) < 0)
|
|
Markus Armbruster |
dfed210 |
+ if (bdrv_open2(bs_table[hd_index + (is_scsi ? MAX_DISKS : 0)],
|
|
Markus Armbruster |
dfed210 |
+ params, 0 /* snapshot */, drv) < 0)
|
|
Markus Armbruster |
dfed210 |
fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
|
|
Markus Armbruster |
dfed210 |
params);
|
|
Markus Armbruster |
dfed210 |
}
|
|
Markus Armbruster |
dfed210 |
@@ -242,6 +257,7 @@ void xenstore_parse_domain_config(int do
|
|
Markus Armbruster |
dfed210 |
out:
|
|
Markus Armbruster |
dfed210 |
free(type);
|
|
Markus Armbruster |
dfed210 |
free(params);
|
|
Markus Armbruster |
dfed210 |
+ free(format);
|
|
Markus Armbruster |
dfed210 |
free(dev);
|
|
Markus Armbruster |
dfed210 |
free(bpath);
|
|
Markus Armbruster |
dfed210 |
free(buf);
|
|
Markus Armbruster |
dfed210 |
diff -rup --exclude '*~' a/tools/python/xen/xend/XendOptions.py b/tools/python/xen/xend/XendOptions.py
|
|
Markus Armbruster |
dfed210 |
--- a/tools/python/xen/xend/XendOptions.py 2008-01-16 19:34:59.000000000 +0100
|
|
Markus Armbruster |
dfed210 |
+++ b/tools/python/xen/xend/XendOptions.py 2008-05-05 14:36:23.000000000 +0200
|
|
Markus Armbruster |
dfed210 |
@@ -314,6 +314,9 @@ class XendOptions:
|
|
Markus Armbruster |
dfed210 |
def get_vnc_x509_verify(self):
|
|
Markus Armbruster |
dfed210 |
return self.get_config_string('vnc-x509-verify', self.xend_vnc_x509_verify)
|
|
Markus Armbruster |
dfed210 |
|
|
Markus Armbruster |
dfed210 |
+ def get_enable_image_format_probing(self):
|
|
Markus Armbruster |
dfed210 |
+ return self.get_config_bool('enable-image-format-probing', 'no')
|
|
Markus Armbruster |
dfed210 |
+
|
|
Markus Armbruster |
dfed210 |
|
|
Markus Armbruster |
dfed210 |
class XendOptionsFile(XendOptions):
|
|
Markus Armbruster |
dfed210 |
|
|
Markus Armbruster |
dfed210 |
diff -rup --exclude '*~' a/tools/python/xen/xend/server/blkif.py b/tools/python/xen/xend/server/blkif.py
|
|
Markus Armbruster |
dfed210 |
--- a/tools/python/xen/xend/server/blkif.py 2008-01-16 19:34:59.000000000 +0100
|
|
Markus Armbruster |
dfed210 |
+++ b/tools/python/xen/xend/server/blkif.py 2008-05-05 14:36:22.000000000 +0200
|
|
Markus Armbruster |
dfed210 |
@@ -21,6 +21,7 @@ import string
|
|
Markus Armbruster |
dfed210 |
|
|
Markus Armbruster |
dfed210 |
from xen.util import blkif
|
|
Markus Armbruster |
dfed210 |
import xen.util.xsm.xsm as security
|
|
Markus Armbruster |
dfed210 |
+from xen.xend import XendOptions
|
|
Markus Armbruster |
dfed210 |
from xen.xend.XendError import VmError
|
|
Markus Armbruster |
dfed210 |
from xen.xend.server.DevController import DevController
|
|
Markus Armbruster |
dfed210 |
|
|
Markus Armbruster |
dfed210 |
@@ -75,6 +76,10 @@ class BlkifController(DevController):
|
|
Markus Armbruster |
dfed210 |
if security.on():
|
|
Markus Armbruster |
dfed210 |
self.do_access_control(config, uname)
|
|
Markus Armbruster |
dfed210 |
|
|
Markus Armbruster |
dfed210 |
+ xoptions = XendOptions.instance()
|
|
Markus Armbruster |
dfed210 |
+ if not xoptions.get_enable_image_format_probing():
|
|
Markus Armbruster |
dfed210 |
+ back.update({'format' : 'raw'})
|
|
Markus Armbruster |
dfed210 |
+
|
|
Markus Armbruster |
dfed210 |
devid = blkif.blkdev_name_to_number(dev)
|
|
Markus Armbruster |
dfed210 |
if devid is None:
|
|
Markus Armbruster |
dfed210 |
raise VmError('Unable to find number for device (%s)' % (dev))
|