aboutsummaryrefslogtreecommitdiff
path: root/block/qcow2-refcount.c
diff options
context:
space:
mode:
authorAlberto Garcia <berto@igalia.com>2018-03-06 18:14:12 +0200
committerKevin Wolf <kwolf@redhat.com>2018-03-09 15:17:47 +0100
commit0c2ada8136a993b1fae9cee2c26b357e9c56c016 (patch)
tree73a42021cb247729f0b834a31d114927ed381814 /block/qcow2-refcount.c
parentdb5794f1f17d1f8247c0ea8e6f0376a47b112466 (diff)
qcow2: Make qemu-img check detect corrupted L1 tables in snapshots
'qemu-img check' cannot detect if a snapshot's L1 table is corrupted. This patch checks the table's offset and size and reports corruption if the values are not valid. This patch doesn't add code to fix that corruption yet, only to detect and report it. 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/qcow2-refcount.c')
-rw-r--r--block/qcow2-refcount.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index b18ea0ca98..362deaf303 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -2047,6 +2047,20 @@ static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
/* snapshots */
for (i = 0; i < s->nb_snapshots; i++) {
sn = s->snapshots + i;
+ if (offset_into_cluster(s, sn->l1_table_offset)) {
+ fprintf(stderr, "ERROR snapshot %s (%s) l1_offset=%#" PRIx64 ": "
+ "L1 table is not cluster aligned; snapshot table entry "
+ "corrupted\n", sn->id_str, sn->name, sn->l1_table_offset);
+ res->corruptions++;
+ continue;
+ }
+ if (sn->l1_size > QCOW_MAX_L1_SIZE / sizeof(uint64_t)) {
+ fprintf(stderr, "ERROR snapshot %s (%s) l1_size=%#" PRIx32 ": "
+ "L1 table is too large; snapshot table entry corrupted\n",
+ sn->id_str, sn->name, sn->l1_size);
+ res->corruptions++;
+ continue;
+ }
ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters,
sn->l1_table_offset, sn->l1_size, 0, fix);
if (ret < 0) {