[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PATCH 7/7] qcow2: Make qemu-img check detect corrupted L1
From: |
Alberto Garcia |
Subject: |
[Qemu-block] [PATCH 7/7] qcow2: Make qemu-img check detect corrupted L1 tables in snapshots |
Date: |
Thu, 1 Mar 2018 18:27:13 +0200 |
'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>
---
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 dcb96e2b16..b1828d6fce 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -2019,6 +2019,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 f16fd59053..2dad7f46a0 100644
--- a/tests/qemu-iotests/080.out
+++ b/tests/qemu-iotests/080.out
@@ -69,6 +69,16 @@ Failed to flush the refcount block cache: Invalid argument
write failed: Invalid argument
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
@@ -80,4 +90,14 @@ Failed to flush the refcount block cache: File too large
write failed: File 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.11.0
- [Qemu-block] [PATCH 0/7] Add checks for corruption in the snapshot table, Alberto Garcia, 2018/03/01
- [Qemu-block] [PATCH 7/7] qcow2: Make qemu-img check detect corrupted L1 tables in snapshots,
Alberto Garcia <=
- [Qemu-block] [PATCH 6/7] qcow2: Check snapshot L1 table in qcow2_snapshot_delete(), Alberto Garcia, 2018/03/01
- [Qemu-block] [PATCH 4/7] qcow2: Check snapshot L1 tables in qcow2_check_metadata_overlap(), Alberto Garcia, 2018/03/01
- [Qemu-block] [PATCH 2/7] qcow2: Check L1 table offset in qcow2_snapshot_load_tmp(), Alberto Garcia, 2018/03/01
- [Qemu-block] [PATCH 5/7] qcow2: Check snapshot L1 table in qcow2_snapshot_goto(), Alberto Garcia, 2018/03/01
- [Qemu-block] [PATCH 1/7] qcow2: Generalize validate_table_offset() into qcow2_validate_table(), Alberto Garcia, 2018/03/01