Commit 3f6a3ee51ebd1e86c48ff1216f5caf9785913ab5

Authored by Kevin Wolf
Committed by Anthony Liguori
1 parent c53ffce9

qcow2: Fix L1 table memory allocation

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
... ... @@ -47,7 +47,7 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
47 47 #endif
48 48  
49 49 new_l1_size2 = sizeof(uint64_t) * new_l1_size;
50   - new_l1_table = qemu_mallocz(new_l1_size2);
  50 + new_l1_table = qemu_mallocz(align_offset(new_l1_size2, 512));
51 51 memcpy(new_l1_table, s->l1_table, s->l1_size * sizeof(uint64_t));
52 52  
53 53 /* write new table (align to cluster) */
... ...
block/qcow2-refcount.c
... ... @@ -513,7 +513,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
513 513 l1_size2 = l1_size * sizeof(uint64_t);
514 514 l1_allocated = 0;
515 515 if (l1_table_offset != s->l1_table_offset) {
516   - l1_table = qemu_malloc(l1_size2);
  516 + l1_table = qemu_mallocz(align_offset(l1_size2, 512));
517 517 l1_allocated = 1;
518 518 if (bdrv_pread(s->hd, l1_table_offset,
519 519 l1_table, l1_size2) != l1_size2)
... ...
block/qcow2.c
... ... @@ -200,7 +200,8 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
200 200 if (s->l1_size < s->l1_vm_state_index)
201 201 goto fail;
202 202 s->l1_table_offset = header.l1_table_offset;
203   - s->l1_table = qemu_malloc(s->l1_size * sizeof(uint64_t));
  203 + s->l1_table = qemu_mallocz(
  204 + align_offset(s->l1_size * sizeof(uint64_t), 512));
204 205 if (bdrv_pread(s->hd, s->l1_table_offset, s->l1_table, s->l1_size * sizeof(uint64_t)) !=
205 206 s->l1_size * sizeof(uint64_t))
206 207 goto fail;
... ...