summaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2014-03-26 13:05:33 +0100
committerMichael Roth <mdroth@linux.vnet.ibm.com>2014-07-03 16:18:11 -0500
commit6b94cfeca8f9727ae6de41f2b53f1f906620c49a (patch)
treeb6f76aae7e7da53c513cbc906272ebebae1fec38 /block
parent0e748624bd2261e7589b40b31413d62dc841957a (diff)
downloadqemu-6b94cfeca8f9727ae6de41f2b53f1f906620c49a.tar.gz
bochs: Check catalog_size header field (CVE-2014-0143)
It should neither become negative nor allow unbounded memory allocations. This fixes aborts in g_malloc() and an s->catalog_bitmap buffer overflow on big endian hosts. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> (cherry picked from commit e3737b820b45e54b059656dc3f914f895ac7a88b) Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Diffstat (limited to 'block')
-rw-r--r--block/bochs.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/block/bochs.c b/block/bochs.c
index 04cca7110d..d1b1a2c6cc 100644
--- a/block/bochs.c
+++ b/block/bochs.c
@@ -122,7 +122,14 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
bs->total_sectors = le64_to_cpu(bochs.extra.redolog.disk) / 512;
}
+ /* Limit to 1M entries to avoid unbounded allocation. This is what is
+ * needed for the largest image that bximage can create (~8 TB). */
s->catalog_size = le32_to_cpu(bochs.catalog);
+ if (s->catalog_size > 0x100000) {
+ error_setg(errp, "Catalog size is too large");
+ return -EFBIG;
+ }
+
s->catalog_bitmap = g_malloc(s->catalog_size * 4);
ret = bdrv_pread(bs->file, le32_to_cpu(bochs.header), s->catalog_bitmap,
@@ -141,6 +148,12 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
s->extent_size = le32_to_cpu(bochs.extent);
+ if (s->catalog_size < bs->total_sectors / s->extent_size) {
+ error_setg(errp, "Catalog size is too small for this disk size");
+ ret = -EINVAL;
+ goto fail;
+ }
+
qemu_co_mutex_init(&s->lock);
return 0;