[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 082/156] vpc/vhd: add bounds check for max_table_ent
From: |
Michael Roth |
Subject: |
[Qemu-devel] [PATCH 082/156] vpc/vhd: add bounds check for max_table_entries and block_size (CVE-2014-0144) |
Date: |
Tue, 8 Jul 2014 12:17:53 -0500 |
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>
(cherry picked from commit 97f1c45c6f456572e5b504b8614e4a69e23b8e3a)
Signed-off-by: Michael Roth <address@hidden>
---
block/vpc.c | 27 +++++++++++++++++++++++----
1 file changed, 23 insertions(+), 4 deletions(-)
diff --git a/block/vpc.c b/block/vpc.c
index 577cc45..4acf154 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;
@@ -221,7 +224,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;
}
@@ -244,7 +247,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);
@@ -297,7 +316,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
@@ -819,7 +838,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.1
- [Qemu-devel] [PATCH 106/156] dmg: sanitize chunk length and sectorcount (CVE-2014-0145), (continued)
- [Qemu-devel] [PATCH 106/156] dmg: sanitize chunk length and sectorcount (CVE-2014-0145), Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 071/156] block/cloop: validate block_size header field (CVE-2014-0144), Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 019/156] ide: Correct improper smart self test counter reset in ide core., Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 111/156] qcow2: Fix copy_sectors() with VM state, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 007/156] scsi: Change scsi sense buf size to 252, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 081/156] bochs: Fix bitmap offset calculation, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 043/156] Fix vmstate_info_int32_le comparison/assign, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 014/156] virtio-net: Do not filter VLANs without F_CTRL_VLAN, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 101/156] qcow2: Fix new L1 table size check (CVE-2014-0143), Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 103/156] dmg: prevent out-of-bounds array access on terminator, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 082/156] vpc/vhd: add bounds check for max_table_entries and block_size (CVE-2014-0144),
Michael Roth <=
- [Qemu-devel] [PATCH 152/156] qapi: zero-initialize all QMP command parameters, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 023/156] block: Use BDRV_O_NO_BACKING where appropriate, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 140/156] scsi-disk: fix bug in scsi_block_new_request() introduced by commit 137745c, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 067/156] migration: remove duplicate code, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 092/156] qcow2: Validate active L1 table offset and size (CVE-2014-0144), Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 009/156] tap: avoid deadlocking rx, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 008/156] qom: Avoid leaking str and bool properties on failure, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 011/156] configure: Don't use __int128_t for clang versions before 3.2, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 114/156] parallels: Fix catalog size integer overflow (CVE-2014-0143), Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 015/156] hw/net/stellaris_enet: Restructure tx_fifo code to avoid buffer overrun, Michael Roth, 2014/07/08