qcow2: Fix L1 table memory allocation
authorKevin Wolf <kwolf@redhat.com>
Tue, 7 Jul 2009 16:09:42 +0000 (18:09 +0200)
committerAnthony Liguori <aliguori@us.ibm.com>
Fri, 10 Jul 2009 18:44:29 +0000 (13:44 -0500)
Contrary to what one could expect, the size of L1 tables is not cluster
aligned. So as we're writing whole sectors now instead of single entries,
we need to ensure that the L1 table in memory is large enough; otherwise
write would access memory after the end of the L1 table.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
block/qcow2-cluster.c
block/qcow2-refcount.c
block/qcow2.c

index d349655d0cc5b614d604c040e8897691137ea7e7..057dac57382368ca3b80046f6c1a62ec3c422be8 100644 (file)
@@ -47,7 +47,7 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
 #endif
 
     new_l1_size2 = sizeof(uint64_t) * new_l1_size;
-    new_l1_table = qemu_mallocz(new_l1_size2);
+    new_l1_table = qemu_mallocz(align_offset(new_l1_size2, 512));
     memcpy(new_l1_table, s->l1_table, s->l1_size * sizeof(uint64_t));
 
     /* write new table (align to cluster) */
index d42c6e6461d0e3a2e2956f550be7e1bd8eefff0f..e6c857e0843fb045dcaa20b4d97a53cbe38f69fb 100644 (file)
@@ -513,7 +513,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
     l1_size2 = l1_size * sizeof(uint64_t);
     l1_allocated = 0;
     if (l1_table_offset != s->l1_table_offset) {
-        l1_table = qemu_malloc(l1_size2);
+        l1_table = qemu_mallocz(align_offset(l1_size2, 512));
         l1_allocated = 1;
         if (bdrv_pread(s->hd, l1_table_offset,
                        l1_table, l1_size2) != l1_size2)
index 9a7c666ee735deaf68e9bae579b67bf0f4aa7030..be507e7a9c1e5e01eae74e0e24c4e0016c3af1a3 100644 (file)
@@ -200,7 +200,8 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
     if (s->l1_size < s->l1_vm_state_index)
         goto fail;
     s->l1_table_offset = header.l1_table_offset;
-    s->l1_table = qemu_malloc(s->l1_size * sizeof(uint64_t));
+    s->l1_table = qemu_mallocz(
+        align_offset(s->l1_size * sizeof(uint64_t), 512));
     if (bdrv_pread(s->hd, s->l1_table_offset, s->l1_table, s->l1_size * sizeof(uint64_t)) !=
         s->l1_size * sizeof(uint64_t))
         goto fail;