Commit 1e72d3b7ad9108fec5cb90d38ddfd00bdf498db2

Authored by aurel32
1 parent 5b257578

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
Showing 2 changed files with 15 additions and 2 deletions
qemu-doc.texi
@@ -261,6 +261,10 @@ These options have the same definition as they have in @option{-hdachs}. @@ -261,6 +261,10 @@ These options have the same definition as they have in @option{-hdachs}.
261 @var{snapshot} is "on" or "off" and allows to enable snapshot for given drive (see @option{-snapshot}). 261 @var{snapshot} is "on" or "off" and allows to enable snapshot for given drive (see @option{-snapshot}).
262 @item cache=@var{cache} 262 @item cache=@var{cache}
263 @var{cache} is "on" or "off" and allows to disable host cache to access data. 263 @var{cache} is "on" or "off" and allows to disable host cache to access data.
  264 +@item format=@var{format}
  265 +Specify which disk @var{format} will be used rather than detecting
  266 +the format. Can be used to specifiy format=raw to avoid interpreting
  267 +an untrusted format header.
264 @end table 268 @end table
265 269
266 Instead of @option{-cdrom} you can use: 270 Instead of @option{-cdrom} you can use:
@@ -4961,6 +4961,7 @@ static int drive_init(struct drive_opt *arg, int snapshot, @@ -4961,6 +4961,7 @@ static int drive_init(struct drive_opt *arg, int snapshot,
4961 int bus_id, unit_id; 4961 int bus_id, unit_id;
4962 int cyls, heads, secs, translation; 4962 int cyls, heads, secs, translation;
4963 BlockDriverState *bdrv; 4963 BlockDriverState *bdrv;
  4964 + BlockDriver *drv = NULL;
4964 int max_devs; 4965 int max_devs;
4965 int index; 4966 int index;
4966 int cache; 4967 int cache;
@@ -4968,7 +4969,7 @@ static int drive_init(struct drive_opt *arg, int snapshot, @@ -4968,7 +4969,7 @@ static int drive_init(struct drive_opt *arg, int snapshot,
4968 char *str = arg->opt; 4969 char *str = arg->opt;
4969 char *params[] = { "bus", "unit", "if", "index", "cyls", "heads", 4970 char *params[] = { "bus", "unit", "if", "index", "cyls", "heads",
4970 "secs", "trans", "media", "snapshot", "file", 4971 "secs", "trans", "media", "snapshot", "file",
4971 - "cache", NULL }; 4972 + "cache", "format", NULL };
4972 4973
4973 if (check_params(buf, sizeof(buf), params, str) < 0) { 4974 if (check_params(buf, sizeof(buf), params, str) < 0) {
4974 fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n", 4975 fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n",
@@ -5136,6 +5137,14 @@ static int drive_init(struct drive_opt *arg, int snapshot, @@ -5136,6 +5137,14 @@ static int drive_init(struct drive_opt *arg, int snapshot,
5136 } 5137 }
5137 } 5138 }
5138 5139
  5140 + if (get_param_value(buf, sizeof(buf), "format", str)) {
  5141 + drv = bdrv_find_format(buf);
  5142 + if (!drv) {
  5143 + fprintf(stderr, "qemu: '%s' invalid format\n", buf);
  5144 + return -1;
  5145 + }
  5146 + }
  5147 +
5139 if (arg->file == NULL) 5148 if (arg->file == NULL)
5140 get_param_value(file, sizeof(file), "file", str); 5149 get_param_value(file, sizeof(file), "file", str);
5141 else 5150 else
@@ -5238,7 +5247,7 @@ static int drive_init(struct drive_opt *arg, int snapshot, @@ -5238,7 +5247,7 @@ static int drive_init(struct drive_opt *arg, int snapshot,
5238 bdrv_flags |= BDRV_O_SNAPSHOT; 5247 bdrv_flags |= BDRV_O_SNAPSHOT;
5239 if (!cache) 5248 if (!cache)
5240 bdrv_flags |= BDRV_O_DIRECT; 5249 bdrv_flags |= BDRV_O_DIRECT;
5241 - if (bdrv_open(bdrv, file, bdrv_flags) < 0 || qemu_key_check(bdrv, file)) { 5250 + if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0 || qemu_key_check(bdrv, file)) {
5242 fprintf(stderr, "qemu: could not open disk image %s\n", 5251 fprintf(stderr, "qemu: could not open disk image %s\n",
5243 file); 5252 file);
5244 return -1; 5253 return -1;