[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL for-2.0 17/51] vpc/vhd: add bounds check for max_tabl
From: |
Stefan Hajnoczi |
Subject: |
[Qemu-devel] [PULL for-2.0 17/51] vpc/vhd: add bounds check for max_table_entries and block_size (CVE-2014-0144) |
Date: |
Tue, 1 Apr 2014 19:18:55 +0200 |
From: Jeff Cody <address@hidden>
This adds checks to make sure that max_table_entries and block_size
are in sane ranges. Memory is allocated based on max_table_entries,
and block_size is used to calculate indices into that allocated
memory, so if these values are incorrect that can lead to potential
unbounded memory allocation, or invalid memory accesses.
Also, the allocation of the pagetable is changed from g_malloc0()
to qemu_blockalign().
Signed-off-by: Jeff Cody <address@hidden>
Signed-off-by: Kevin Wolf <address@hidden>
Reviewed-by: Max Reitz <address@hidden>
Signed-off-by: Stefan Hajnoczi <address@hidden>
---
block/vpc.c | 27 +++++++++++++++++++++++----
1 file changed, 23 insertions(+), 4 deletions(-)
diff --git a/block/vpc.c b/block/vpc.c
index 82bf248..ba82d48 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -45,6 +45,8 @@ enum vhd_type {
// Seconds since Jan 1, 2000 0:00:00 (UTC)
#define VHD_TIMESTAMP_BASE 946684800
+#define VHD_MAX_SECTORS (65535LL * 255 * 255)
+
// always big-endian
typedef struct vhd_footer {
char creator[8]; // "conectix"
@@ -164,6 +166,7 @@ static int vpc_open(BlockDriverState *bs, QDict *options,
int flags,
VHDDynDiskHeader *dyndisk_header;
uint8_t buf[HEADER_SIZE];
uint32_t checksum;
+ uint64_t computed_size;
int disk_type = VHD_DYNAMIC;
int ret;
@@ -222,7 +225,7 @@ static int vpc_open(BlockDriverState *bs, QDict *options,
int flags,
}
/* Allow a maximum disk size of approximately 2 TB */
- if (bs->total_sectors >= 65535LL * 255 * 255) {
+ if (bs->total_sectors >= VHD_MAX_SECTORS) {
ret = -EFBIG;
goto fail;
}
@@ -245,7 +248,23 @@ static int vpc_open(BlockDriverState *bs, QDict *options,
int flags,
s->bitmap_size = ((s->block_size / (8 * 512)) + 511) & ~511;
s->max_table_entries = be32_to_cpu(dyndisk_header->max_table_entries);
- s->pagetable = g_malloc(s->max_table_entries * 4);
+
+ if ((bs->total_sectors * 512) / s->block_size > 0xffffffffU) {
+ ret = -EINVAL;
+ goto fail;
+ }
+ if (s->max_table_entries > (VHD_MAX_SECTORS * 512) / s->block_size) {
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ computed_size = (uint64_t) s->max_table_entries * s->block_size;
+ if (computed_size < bs->total_sectors * 512) {
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ s->pagetable = qemu_blockalign(bs, s->max_table_entries * 4);
s->bat_offset = be64_to_cpu(dyndisk_header->table_offset);
@@ -298,7 +317,7 @@ static int vpc_open(BlockDriverState *bs, QDict *options,
int flags,
return 0;
fail:
- g_free(s->pagetable);
+ qemu_vfree(s->pagetable);
#ifdef CACHE
g_free(s->pageentry_u8);
#endif
@@ -833,7 +852,7 @@ static int vpc_has_zero_init(BlockDriverState *bs)
static void vpc_close(BlockDriverState *bs)
{
BDRVVPCState *s = bs->opaque;
- g_free(s->pagetable);
+ qemu_vfree(s->pagetable);
#ifdef CACHE
g_free(s->pageentry_u8);
#endif
--
1.9.0
- [Qemu-devel] [PULL for-2.0 04/51] qemu-iotests: add ./check -cloop support, (continued)
- [Qemu-devel] [PULL for-2.0 04/51] qemu-iotests: add ./check -cloop support, Stefan Hajnoczi, 2014/04/01
- [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 <=
- [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, 2014/04/01
- [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