[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PULL 14/56] qcow2: Make qemu-img check detect corrupted L1
From: |
Kevin Wolf |
Subject: |
[Qemu-block] [PULL 14/56] qcow2: Make qemu-img check detect corrupted L1 tables in snapshots |
Date: |
Fri, 9 Mar 2018 17:18:51 +0100 |
From: Alberto Garcia <address@hidden>
'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 <address@hidden>
Reviewed-by: Eric Blake <address@hidden>
Signed-off-by: Kevin Wolf <address@hidden>
---
block/qcow2-refcount.c | 14 ++++++++++++++
tests/qemu-iotests/080 | 2 ++
tests/qemu-iotests/080.out | 20 ++++++++++++++++++++
3 files changed, 36 insertions(+)
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) {
diff --git a/tests/qemu-iotests/080 b/tests/qemu-iotests/080
index f8e7d6f4df..4dbe68e950 100755
--- a/tests/qemu-iotests/080
+++ b/tests/qemu-iotests/080
@@ -182,6 +182,7 @@ poke_file "$TEST_IMG" "$offset_snap1_l1_offset"
"\x00\x00\x00\x00\x00\x40\x02\x0
-c 'write 0 4k'; } 2>&1 | _filter_qemu_io | _filter_testdir
{ $QEMU_IMG snapshot -a test $TEST_IMG; } 2>&1 | _filter_testdir
{ $QEMU_IMG snapshot -d test $TEST_IMG; } 2>&1 | _filter_testdir
+_check_test_img
echo
echo "== Invalid snapshot L1 table size =="
@@ -195,6 +196,7 @@ poke_file "$TEST_IMG" "$offset_snap1_l1_size"
"\x10\x00\x00\x00"
-c 'write 0 4k'; } 2>&1 | _filter_qemu_io | _filter_testdir
{ $QEMU_IMG snapshot -a test $TEST_IMG; } 2>&1 | _filter_testdir
{ $QEMU_IMG snapshot -d test $TEST_IMG; } 2>&1 | _filter_testdir
+_check_test_img
# success, all done
echo "*** done"
diff --git a/tests/qemu-iotests/080.out b/tests/qemu-iotests/080.out
index 89bcd27172..4e0f7f7b92 100644
--- a/tests/qemu-iotests/080.out
+++ b/tests/qemu-iotests/080.out
@@ -71,6 +71,16 @@ write failed: Invalid argument
qemu-img: Snapshot L1 table offset invalid
qemu-img: Could not apply snapshot 'test': Failed to load snapshot: Invalid
argument
qemu-img: Could not delete snapshot 'test': Snapshot L1 table offset invalid
+ERROR snapshot 1 (test) l1_offset=0x400200: L1 table is not cluster aligned;
snapshot table entry corrupted
+Leaked cluster 4 refcount=2 reference=1
+Leaked cluster 5 refcount=2 reference=1
+Leaked cluster 6 refcount=1 reference=0
+
+1 errors were found on the image.
+Data may be corrupted, or further writes to the image may corrupt it.
+
+3 leaked clusters were found on the image.
+This means waste of disk space, but no harm to data.
== Invalid snapshot L1 table size ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
@@ -84,4 +94,14 @@ write failed: File too large
qemu-img: Snapshot L1 table too large
qemu-img: Could not apply snapshot 'test': Failed to load snapshot: File too
large
qemu-img: Could not delete snapshot 'test': Snapshot L1 table too large
+ERROR snapshot 1 (test) l1_size=0x10000000: L1 table is too large; snapshot
table entry corrupted
+Leaked cluster 4 refcount=2 reference=1
+Leaked cluster 5 refcount=2 reference=1
+Leaked cluster 6 refcount=1 reference=0
+
+1 errors were found on the image.
+Data may be corrupted, or further writes to the image may corrupt it.
+
+3 leaked clusters were found on the image.
+This means waste of disk space, but no harm to data.
*** done
--
2.13.6
- [Qemu-block] [PULL 01/56] block: implement the bdrv_reopen_prepare helper for LUKS driver, (continued)
- [Qemu-block] [PULL 01/56] block: implement the bdrv_reopen_prepare helper for LUKS driver, Kevin Wolf, 2018/03/09
- [Qemu-block] [PULL 04/56] qcow2: make qcow2_do_open a coroutine_fn, Kevin Wolf, 2018/03/09
- [Qemu-block] [PULL 09/56] qcow2: Check L1 table offset in qcow2_snapshot_load_tmp(), Kevin Wolf, 2018/03/09
- [Qemu-block] [PULL 08/56] qcow2: Generalize validate_table_offset() into qcow2_validate_table(), Kevin Wolf, 2018/03/09
- [Qemu-block] [PULL 06/56] block: convert bdrv_invalidate_cache callback to coroutine_fn, Kevin Wolf, 2018/03/09
- [Qemu-block] [PULL 07/56] block: convert bdrv_check callback to coroutine_fn, Kevin Wolf, 2018/03/09
- [Qemu-block] [PULL 11/56] qcow2: Check snapshot L1 tables in qcow2_check_metadata_overlap(), Kevin Wolf, 2018/03/09
- [Qemu-block] [PULL 12/56] qcow2: Check snapshot L1 table in qcow2_snapshot_goto(), Kevin Wolf, 2018/03/09
- [Qemu-block] [PULL 13/56] qcow2: Check snapshot L1 table in qcow2_snapshot_delete(), Kevin Wolf, 2018/03/09
- [Qemu-block] [PULL 10/56] qcow2: Check L1 table parameters in qcow2_expand_zero_clusters(), Kevin Wolf, 2018/03/09
- [Qemu-block] [PULL 14/56] qcow2: Make qemu-img check detect corrupted L1 tables in snapshots,
Kevin Wolf <=
- [Qemu-block] [PULL 15/56] block/qapi: Introduce BlockdevCreateOptions, Kevin Wolf, 2018/03/09
- [Qemu-block] [PULL 17/56] qcow2: Rename qcow2_co_create2() to qcow2_co_create(), Kevin Wolf, 2018/03/09
- [Qemu-block] [PULL 22/56] qcow2: Handle full/falloc preallocation in qcow2_co_create(), Kevin Wolf, 2018/03/09
- [Qemu-block] [PULL 18/56] qcow2: Let qcow2_create() handle protocol layer, Kevin Wolf, 2018/03/09
- [Qemu-block] [PULL 21/56] qcow2: Use QCryptoBlockCreateOptions in qcow2_co_create(), Kevin Wolf, 2018/03/09
- [Qemu-block] [PULL 25/56] test-qemu-opts: Test qemu_opts_to_qdict_filtered(), Kevin Wolf, 2018/03/09
- [Qemu-block] [PULL 16/56] block/qapi: Add qcow2 create options to schema, Kevin Wolf, 2018/03/09
- [Qemu-block] [PULL 26/56] qdict: Introduce qdict_rename_keys(), Kevin Wolf, 2018/03/09
- [Qemu-block] [PULL 24/56] test-qemu-opts: Test qemu_opts_append(), Kevin Wolf, 2018/03/09
- [Qemu-block] [PULL 27/56] qcow2: Use visitor for options in qcow2_create(), Kevin Wolf, 2018/03/09