[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-stable] [PATCH 098/156] qcow2: Check new refcount table size on gr
From: |
Michael Roth |
Subject: |
[Qemu-stable] [PATCH 098/156] qcow2: Check new refcount table size on growth |
Date: |
Tue, 8 Jul 2014 12:18:09 -0500 |
From: Kevin Wolf <address@hidden>
If the size becomes larger than what qcow2_open() would accept, fail the
growing operation.
Signed-off-by: Kevin Wolf <address@hidden>
Reviewed-by: Max Reitz <address@hidden>
Signed-off-by: Stefan Hajnoczi <address@hidden>
(cherry picked from commit 2b5d5953eec0cc541857c3df812bdf8421596ab2)
Signed-off-by: Michael Roth <address@hidden>
---
block/qcow2-refcount.c | 4 ++++
block/qcow2.c | 4 +---
block/qcow2.h | 9 +++++++++
3 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 57c1fba..29e25a7 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -310,6 +310,10 @@ static int alloc_refcount_block(BlockDriverState *bs,
uint64_t refcount_block_clusters = 1 << (s->cluster_bits - REFCOUNT_SHIFT);
uint64_t blocks_used = DIV_ROUND_UP(cluster_index,
refcount_block_clusters);
+ if (blocks_used > QCOW_MAX_REFTABLE_SIZE / sizeof(uint64_t)) {
+ return -EFBIG;
+ }
+
/* And now we need at least one block more for the new metadata */
uint64_t table_size = next_refcount_table_size(s, blocks_used + 1);
uint64_t last_table_size;
diff --git a/block/qcow2.c b/block/qcow2.c
index 45f3f8a..447308e 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -611,9 +611,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options,
int flags,
s->refcount_table_size =
header.refcount_table_clusters << (s->cluster_bits - 3);
- if (header.refcount_table_clusters > (0x800000 >> s->cluster_bits)) {
- /* 8 MB refcount table is enough for 2 PB images at 64k cluster size
- * (128 GB for 512 byte clusters, 2 EB for 2 MB clusters) */
+ if (header.refcount_table_clusters > qcow2_max_refcount_clusters(s)) {
error_setg(errp, "Reference count table too large");
ret = -EINVAL;
goto fail;
diff --git a/block/qcow2.h b/block/qcow2.h
index 99fe092..e1b4c4b 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -40,6 +40,10 @@
#define QCOW_MAX_CRYPT_CLUSTERS 32
#define QCOW_MAX_SNAPSHOTS 65536
+/* 8 MB refcount table is enough for 2 PB images at 64k cluster size
+ * (128 GB for 512 byte clusters, 2 EB for 2 MB clusters) */
+#define QCOW_MAX_REFTABLE_SIZE 0x800000
+
/* indicate that the refcount of the referenced cluster is exactly one. */
#define QCOW_OFLAG_COPIED (1ULL << 63)
/* indicate that the cluster is compressed (they never have the copied flag) */
@@ -410,6 +414,11 @@ static inline int64_t qcow2_vm_state_offset(BDRVQcowState
*s)
return (int64_t)s->l1_vm_state_index << (s->cluster_bits + s->l2_bits);
}
+static inline uint64_t qcow2_max_refcount_clusters(BDRVQcowState *s)
+{
+ return QCOW_MAX_REFTABLE_SIZE >> s->cluster_bits;
+}
+
static inline int qcow2_get_cluster_type(uint64_t l2_entry)
{
if (l2_entry & QCOW_OFLAG_COMPRESSED) {
--
1.9.1
- [Qemu-stable] [PATCH 084/156] vdi: add bounds checks for blocks_in_image and disk_size header fields (CVE-2014-0144), (continued)
- [Qemu-stable] [PATCH 084/156] vdi: add bounds checks for blocks_in_image and disk_size header fields (CVE-2014-0144), Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 085/156] vhdx: Bounds checking for block_size and logical_sector_size (CVE-2014-0148), Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 086/156] curl: check data size before memcpy to local buffer. (CVE-2014-0144), Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 089/156] qcow2: Check refcount table size (CVE-2014-0144), Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 087/156] qcow2: Check header_length (CVE-2014-0144), Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 088/156] qcow2: Check backing_file_offset (CVE-2014-0144), Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 094/156] qcow2: fix offset overflow in qcow2_alloc_clusters_at(), Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 091/156] qcow2: Validate snapshot table offset/size (CVE-2014-0144), Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 093/156] qcow2: Fix backing file name length check, Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 097/156] qcow2: Avoid integer overflow in get_refcount (CVE-2014-0143), Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 098/156] qcow2: Check new refcount table size on growth,
Michael Roth <=
- [Qemu-stable] [PATCH 099/156] qcow2: Fix types in qcow2_alloc_clusters and alloc_clusters_noref, Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 107/156] dmg: use uint64_t consistently for sectors and lengths, Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 104/156] dmg: drop broken bdrv_pread() loop, Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 110/156] qcow2: Fix NULL dereference in qcow2_open() error path (CVE-2014-0146), Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 121/156] virtio-scsi: Plug memory leak on virtio_scsi_push_event() error path, Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 124/156] blockdev: Plug memory leak in blockdev_init(), Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 122/156] target-xtensa: fix cross-page jumps/calls at the end of TB, Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 123/156] cputlb: Fix regression with TCG interpreter (bug 1310324), Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 126/156] block/qapi: Plug memory leak in dump_qobject() case QTYPE_QERROR, Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 129/156] block/sheepdog: Plug memory leak in sd_snapshot_create(), Michael Roth, 2014/07/08