diff options
Diffstat (limited to 'block/qcow2-cluster.c')
| -rw-r--r-- | block/qcow2-cluster.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index fb10e26068..a3fec27bf9 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -278,6 +278,14 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table) goto fail; } + /* If we're allocating the table at offset 0 then something is wrong */ + if (l2_offset == 0) { + qcow2_signal_corruption(bs, true, -1, -1, "Preventing invalid " + "allocation of L2 table at offset 0"); + ret = -EIO; + goto fail; + } + ret = qcow2_cache_flush(bs, s->refcount_block_cache); if (ret < 0) { goto fail; @@ -1300,10 +1308,21 @@ static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset, (!*host_offset || start_of_cluster(s, *host_offset) == (entry & L2E_OFFSET_MASK))) { + int preallocated_nb_clusters; + + if (offset_into_cluster(s, entry & L2E_OFFSET_MASK)) { + qcow2_signal_corruption(bs, true, -1, -1, "Preallocated zero " + "cluster offset %#llx unaligned (guest " + "offset: %#" PRIx64 ")", + entry & L2E_OFFSET_MASK, guest_offset); + ret = -EIO; + goto fail; + } + /* Try to reuse preallocated zero clusters; contiguous normal clusters * would be fine, too, but count_cow_clusters() above has limited * nb_clusters already to a range of COW clusters */ - int preallocated_nb_clusters = + preallocated_nb_clusters = count_contiguous_clusters(nb_clusters, s->cluster_size, &l2_table[l2_index], QCOW_OFLAG_COPIED); assert(preallocated_nb_clusters > 0); |