diff options
author | Alberto Garcia <berto@igalia.com> | 2018-03-06 18:14:08 +0200 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2018-03-09 15:17:47 +0100 |
commit | c9a442e45094e693da45f0e3d03746d68e4460ec (patch) | |
tree | cee598bcb6a836264b39b56b8c32aeb97e321782 /block | |
parent | 314e8d3928aa82fa13673d47b5af7bdd9a6d82bf (diff) |
qcow2: Check L1 table parameters in qcow2_expand_zero_clusters()
This function iterates over all snapshots of a qcow2 file in order to
expand all zero clusters, but it does not validate the snapshots' L1
tables first.
We now have a function to take care of this, so let's use it.
We can also take the opportunity to replace the sector-based
bdrv_read() with bdrv_pread().
Cc: Eric Blake <eblake@redhat.com>
Signed-off-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block')
-rw-r--r-- | block/qcow2-cluster.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 98908c4264..1aee726c6a 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -25,6 +25,7 @@ #include "qemu/osdep.h" #include <zlib.h> +#include "qapi/error.h" #include "qemu-common.h" #include "block/block_int.h" #include "block/qcow2.h" @@ -2092,11 +2093,21 @@ int qcow2_expand_zero_clusters(BlockDriverState *bs, } for (i = 0; i < s->nb_snapshots; i++) { - int l1_sectors = DIV_ROUND_UP(s->snapshots[i].l1_size * - sizeof(uint64_t), BDRV_SECTOR_SIZE); + int l1_size2; + uint64_t *new_l1_table; + Error *local_err = NULL; + + ret = qcow2_validate_table(bs, s->snapshots[i].l1_table_offset, + s->snapshots[i].l1_size, sizeof(uint64_t), + QCOW_MAX_L1_SIZE, "Snapshot L1 table", + &local_err); + if (ret < 0) { + error_report_err(local_err); + goto fail; + } - uint64_t *new_l1_table = - g_try_realloc(l1_table, l1_sectors * BDRV_SECTOR_SIZE); + l1_size2 = s->snapshots[i].l1_size * sizeof(uint64_t); + new_l1_table = g_try_realloc(l1_table, l1_size2); if (!new_l1_table) { ret = -ENOMEM; @@ -2105,9 +2116,8 @@ int qcow2_expand_zero_clusters(BlockDriverState *bs, l1_table = new_l1_table; - ret = bdrv_read(bs->file, - s->snapshots[i].l1_table_offset / BDRV_SECTOR_SIZE, - (void *)l1_table, l1_sectors); + ret = bdrv_pread(bs->file, s->snapshots[i].l1_table_offset, + l1_table, l1_size2); if (ret < 0) { goto fail; } |