]> xenbits.xensource.com Git - qemu-upstream-4.4-testing.git/commitdiff
qcow1: Validate image size (CVE-2014-0223)
authorKevin Wolf <kwolf@redhat.com>
Thu, 5 Mar 2015 11:02:27 +0000 (11:02 +0000)
committerStefano Stabellini <stefano.stabellini@eu.citrix.com>
Thu, 5 Mar 2015 15:37:20 +0000 (15:37 +0000)
A huge image size could cause s->l1_size to overflow. Make sure that
images never require a L1 table larger than what fits in s->l1_size.

This cannot only cause unbounded allocations, but also the allocation of
a too small L1 table, resulting in out-of-bounds array accesses (both
reads and writes).

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
block/qcow.c

index da469af401270d1ac06a316ff3fe2e21d89a3eb3..8ecfe60ac2db87c78a5d727e90ac0a78bb857601 100644 (file)
@@ -60,7 +60,7 @@ typedef struct BDRVQcowState {
     int cluster_sectors;
     int l2_bits;
     int l2_size;
-    int l1_size;
+    unsigned int l1_size;
     uint64_t cluster_offset_mask;
     uint64_t l1_table_offset;
     uint64_t *l1_table;
@@ -154,7 +154,17 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags)
 
     /* read the level 1 table */
     shift = s->cluster_bits + s->l2_bits;
-    s->l1_size = (header.size + (1LL << shift) - 1) >> shift;
+    if (header.size > UINT64_MAX - (1LL << shift)) {
+        ret = -EINVAL;
+        goto fail;
+    } else {
+        uint64_t l1_size = (header.size + (1LL << shift) - 1) >> shift;
+        if (l1_size > INT_MAX / sizeof(uint64_t)) {
+            ret = -EINVAL;
+            goto fail;
+        }
+        s->l1_size = l1_size;
+    }
 
     s->l1_table_offset = header.l1_table_offset;
     s->l1_table = g_malloc(s->l1_size * sizeof(uint64_t));