add format= to drive options (CVE-2008-2004)

It is possible for a guest with a raw formatted disk image to write a
header to that disk image describing another format (such as qcow2).
Stopping and subsequent restart of the guest will cause qemu to detect
that format, and could allow the guest to read any host file if qemu is
sufficiently privileged (typical in virt environments).

The patch defaults to existing behaviour (probing based on file contents),
so it still requires the mgmt app (e.g. libvirt xml) to pass a new
"format=raw" parameter for raw disk images.

Originally noted by Avi Kivity, patch from Chris Wright.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4277 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
aurel32 2008-04-28 20:26:45 +00:00
parent 5b2575789b
commit 1e72d3b7ad
2 changed files with 15 additions and 2 deletions

View File

@ -261,6 +261,10 @@ These options have the same definition as they have in @option{-hdachs}.
@var{snapshot} is "on" or "off" and allows to enable snapshot for given drive (see @option{-snapshot}). @var{snapshot} is "on" or "off" and allows to enable snapshot for given drive (see @option{-snapshot}).
@item cache=@var{cache} @item cache=@var{cache}
@var{cache} is "on" or "off" and allows to disable host cache to access data. @var{cache} is "on" or "off" and allows to disable host cache to access data.
@item format=@var{format}
Specify which disk @var{format} will be used rather than detecting
the format. Can be used to specifiy format=raw to avoid interpreting
an untrusted format header.
@end table @end table
Instead of @option{-cdrom} you can use: Instead of @option{-cdrom} you can use:

13
vl.c
View File

@ -4961,6 +4961,7 @@ static int drive_init(struct drive_opt *arg, int snapshot,
int bus_id, unit_id; int bus_id, unit_id;
int cyls, heads, secs, translation; int cyls, heads, secs, translation;
BlockDriverState *bdrv; BlockDriverState *bdrv;
BlockDriver *drv = NULL;
int max_devs; int max_devs;
int index; int index;
int cache; int cache;
@ -4968,7 +4969,7 @@ static int drive_init(struct drive_opt *arg, int snapshot,
char *str = arg->opt; char *str = arg->opt;
char *params[] = { "bus", "unit", "if", "index", "cyls", "heads", char *params[] = { "bus", "unit", "if", "index", "cyls", "heads",
"secs", "trans", "media", "snapshot", "file", "secs", "trans", "media", "snapshot", "file",
"cache", NULL }; "cache", "format", NULL };
if (check_params(buf, sizeof(buf), params, str) < 0) { if (check_params(buf, sizeof(buf), params, str) < 0) {
fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n", fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n",
@ -5136,6 +5137,14 @@ static int drive_init(struct drive_opt *arg, int snapshot,
} }
} }
if (get_param_value(buf, sizeof(buf), "format", str)) {
drv = bdrv_find_format(buf);
if (!drv) {
fprintf(stderr, "qemu: '%s' invalid format\n", buf);
return -1;
}
}
if (arg->file == NULL) if (arg->file == NULL)
get_param_value(file, sizeof(file), "file", str); get_param_value(file, sizeof(file), "file", str);
else else
@ -5238,7 +5247,7 @@ static int drive_init(struct drive_opt *arg, int snapshot,
bdrv_flags |= BDRV_O_SNAPSHOT; bdrv_flags |= BDRV_O_SNAPSHOT;
if (!cache) if (!cache)
bdrv_flags |= BDRV_O_DIRECT; bdrv_flags |= BDRV_O_DIRECT;
if (bdrv_open(bdrv, file, bdrv_flags) < 0 || qemu_key_check(bdrv, file)) { if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0 || qemu_key_check(bdrv, file)) {
fprintf(stderr, "qemu: could not open disk image %s\n", fprintf(stderr, "qemu: could not open disk image %s\n",
file); file);
return -1; return -1;