[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL for-2.0 19/51] vdi: add bounds checks for blocks_in_i
From: |
Stefan Hajnoczi |
Subject: |
[Qemu-devel] [PULL for-2.0 19/51] vdi: add bounds checks for blocks_in_image and disk_size header fields (CVE-2014-0144) |
Date: |
Tue, 1 Apr 2014 19:18:57 +0200 |
From: Jeff Cody <address@hidden>
The maximum blocks_in_image is 0xffffffff / 4, which also limits the
maximum disk_size for a VDI image to 1024TB. Note that this is the maximum
size that QEMU will currently support with this driver, not necessarily the
maximum size allowed by the image format.
This also fixes an incorrect error message, a bug introduced by commit
5b7aa9b56d1bfc79916262f380c3fc7961becb50 (Reported by Stefan Weil)
Signed-off-by: Jeff Cody <address@hidden>
Signed-off-by: Kevin Wolf <address@hidden>
Signed-off-by: Stefan Hajnoczi <address@hidden>
---
block/vdi.c | 37 +++++++++++++++++++++++++++++++++----
1 file changed, 33 insertions(+), 4 deletions(-)
diff --git a/block/vdi.c b/block/vdi.c
index ac9a025..820cd37 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -120,6 +120,11 @@ typedef unsigned char uuid_t[16];
#define VDI_IS_ALLOCATED(X) ((X) < VDI_DISCARDED)
+/* max blocks in image is (0xffffffff / 4) */
+#define VDI_BLOCKS_IN_IMAGE_MAX 0x3fffffff
+#define VDI_DISK_SIZE_MAX ((uint64_t)VDI_BLOCKS_IN_IMAGE_MAX * \
+ (uint64_t)DEFAULT_CLUSTER_SIZE)
+
#if !defined(CONFIG_UUID)
static inline void uuid_generate(uuid_t out)
{
@@ -385,6 +390,14 @@ static int vdi_open(BlockDriverState *bs, QDict *options,
int flags,
vdi_header_print(&header);
#endif
+ if (header.disk_size > VDI_DISK_SIZE_MAX) {
+ error_setg(errp, "Unsupported VDI image size (size is 0x%" PRIx64
+ ", max supported is 0x%" PRIx64 ")",
+ header.disk_size, VDI_DISK_SIZE_MAX);
+ ret = -ENOTSUP;
+ goto fail;
+ }
+
if (header.disk_size % SECTOR_SIZE != 0) {
/* 'VBoxManage convertfromraw' can create images with odd disk sizes.
We accept them but round the disk size to the next multiple of
@@ -420,9 +433,9 @@ static int vdi_open(BlockDriverState *bs, QDict *options,
int flags,
header.sector_size, SECTOR_SIZE);
ret = -ENOTSUP;
goto fail;
- } else if (header.block_size != 1 * MiB) {
- error_setg(errp, "unsupported VDI image (sector size %u is not %u)",
- header.block_size, 1 * MiB);
+ } else if (header.block_size != DEFAULT_CLUSTER_SIZE) {
+ error_setg(errp, "unsupported VDI image (block size %u is not %u)",
+ header.block_size, DEFAULT_CLUSTER_SIZE);
ret = -ENOTSUP;
goto fail;
} else if (header.disk_size >
@@ -441,6 +454,12 @@ static int vdi_open(BlockDriverState *bs, QDict *options,
int flags,
error_setg(errp, "unsupported VDI image (non-NULL parent UUID)");
ret = -ENOTSUP;
goto fail;
+ } else if (header.blocks_in_image > VDI_BLOCKS_IN_IMAGE_MAX) {
+ error_setg(errp, "unsupported VDI image "
+ "(too many blocks %u, max is %u)",
+ header.blocks_in_image, VDI_BLOCKS_IN_IMAGE_MAX);
+ ret = -ENOTSUP;
+ goto fail;
}
bs->total_sectors = header.disk_size / SECTOR_SIZE;
@@ -689,11 +708,20 @@ static int vdi_create(const char *filename,
QEMUOptionParameter *options,
options++;
}
+ if (bytes > VDI_DISK_SIZE_MAX) {
+ result = -ENOTSUP;
+ error_setg(errp, "Unsupported VDI image size (size is 0x%" PRIx64
+ ", max supported is 0x%" PRIx64 ")",
+ bytes, VDI_DISK_SIZE_MAX);
+ goto exit;
+ }
+
fd = qemu_open(filename,
O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
0644);
if (fd < 0) {
- return -errno;
+ result = -errno;
+ goto exit;
}
/* We need enough blocks to store the given disk size,
@@ -754,6 +782,7 @@ static int vdi_create(const char *filename,
QEMUOptionParameter *options,
result = -errno;
}
+exit:
return result;
}
--
1.9.0
- [Qemu-devel] [PULL for-2.0 06/51] block/cloop: validate block_size header field (CVE-2014-0144), (continued)
- [Qemu-devel] [PULL for-2.0 06/51] block/cloop: validate block_size header field (CVE-2014-0144), Stefan Hajnoczi, 2014/04/01
- [Qemu-devel] [PULL for-2.0 07/51] block/cloop: prevent offsets_size integer overflow (CVE-2014-0143), Stefan Hajnoczi, 2014/04/01
- [Qemu-devel] [PULL for-2.0 08/51] block/cloop: refuse images with huge offsets arrays (CVE-2014-0144), Stefan Hajnoczi, 2014/04/01
- [Qemu-devel] [PULL for-2.0 10/51] block/cloop: fix offsets[] size off-by-one, Stefan Hajnoczi, 2014/04/01
- [Qemu-devel] [PULL for-2.0 15/51] bochs: Check extent_size header field (CVE-2014-0142), Stefan Hajnoczi, 2014/04/01
- [Qemu-devel] [PULL for-2.0 12/51] bochs: Unify header structs and make them QEMU_PACKED, Stefan Hajnoczi, 2014/04/01
- [Qemu-devel] [PULL for-2.0 13/51] bochs: Use unsigned variables for offsets and sizes (CVE-2014-0147), Stefan Hajnoczi, 2014/04/01
- [Qemu-devel] [PULL for-2.0 16/51] bochs: Fix bitmap offset calculation, Stefan Hajnoczi, 2014/04/01
- [Qemu-devel] [PULL for-2.0 18/51] vpc: Validate block size (CVE-2014-0142), Stefan Hajnoczi, 2014/04/01
- [Qemu-devel] [PULL for-2.0 17/51] vpc/vhd: add bounds check for max_table_entries and block_size (CVE-2014-0144), Stefan Hajnoczi, 2014/04/01
- [Qemu-devel] [PULL for-2.0 19/51] vdi: add bounds checks for blocks_in_image and disk_size header fields (CVE-2014-0144),
Stefan Hajnoczi <=
- [Qemu-devel] [PULL for-2.0 21/51] curl: check data size before memcpy to local buffer. (CVE-2014-0144), Stefan Hajnoczi, 2014/04/01
- [Qemu-devel] [PULL for-2.0 20/51] vhdx: Bounds checking for block_size and logical_sector_size (CVE-2014-0148), Stefan Hajnoczi, 2014/04/01
- [Qemu-devel] [PULL for-2.0 22/51] qcow2: Check header_length (CVE-2014-0144), Stefan Hajnoczi, 2014/04/01
- [Qemu-devel] [PULL for-2.0 23/51] qcow2: Check backing_file_offset (CVE-2014-0144), Stefan Hajnoczi, 2014/04/01
- [Qemu-devel] [PULL for-2.0 25/51] qcow2: Validate refcount table offset, Stefan Hajnoczi, 2014/04/01
- [Qemu-devel] [PULL for-2.0 24/51] qcow2: Check refcount table size (CVE-2014-0144), Stefan Hajnoczi, 2014/04/01
- [Qemu-devel] [PULL for-2.0 26/51] qcow2: Validate snapshot table offset/size (CVE-2014-0144), Stefan Hajnoczi, 2014/04/01
- [Qemu-devel] [PULL for-2.0 27/51] qcow2: Validate active L1 table offset and size (CVE-2014-0144), Stefan Hajnoczi, 2014/04/01
- [Qemu-devel] [PULL for-2.0 28/51] qcow2: Fix backing file name length check, Stefan Hajnoczi, 2014/04/01
- [Qemu-devel] [PULL for-2.0 29/51] qcow2: Don't rely on free_cluster_index in alloc_refcount_block() (CVE-2014-0147), Stefan Hajnoczi, 2014/04/01