diff options
author | Alberto Garcia <berto@igalia.com> | 2018-03-06 18:14:11 +0200 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2018-03-09 15:17:47 +0100 |
commit | db5794f1f17d1f8247c0ea8e6f0376a47b112466 (patch) | |
tree | ffdca4121775ac6d8d36079310908c8b499e13e1 | |
parent | a8475d7573c0598ba8f92f84534110218ee11e3d (diff) | |
download | qemu-db5794f1f17d1f8247c0ea8e6f0376a47b112466.zip qemu-db5794f1f17d1f8247c0ea8e6f0376a47b112466.tar.gz qemu-db5794f1f17d1f8247c0ea8e6f0376a47b112466.tar.bz2 |
qcow2: Check snapshot L1 table in qcow2_snapshot_delete()
This function deletes a snapshot from disk, removing its entry from
the snapshot table, freeing its L1 table and decreasing the refcounts
of all clusters.
The L1 table offset and size are however not validated. If we use
invalid values in this function we'll probably corrupt the image even
more, so we should return an error instead.
We now have a function to take care of this, so let's use it.
Signed-off-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
-rw-r--r-- | block/qcow2-snapshot.c | 7 | ||||
-rwxr-xr-x | tests/qemu-iotests/080 | 2 | ||||
-rw-r--r-- | tests/qemu-iotests/080.out | 2 |
3 files changed, 11 insertions, 0 deletions
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index 0faf728..74293be 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -611,6 +611,13 @@ int qcow2_snapshot_delete(BlockDriverState *bs, } sn = s->snapshots[snapshot_index]; + ret = qcow2_validate_table(bs, sn.l1_table_offset, sn.l1_size, + sizeof(uint64_t), QCOW_MAX_L1_SIZE, + "Snapshot L1 table", errp); + if (ret < 0) { + return ret; + } + /* Remove it from the snapshot list */ memmove(s->snapshots + snapshot_index, s->snapshots + snapshot_index + 1, diff --git a/tests/qemu-iotests/080 b/tests/qemu-iotests/080 index 5388573..f8e7d6f 100755 --- a/tests/qemu-iotests/080 +++ b/tests/qemu-iotests/080 @@ -181,6 +181,7 @@ poke_file "$TEST_IMG" "$offset_snap1_l1_offset" "\x00\x00\x00\x00\x00\x40\x02\x0 { $QEMU_IO -c "open -o overlap-check.inactive-l2=on $TEST_IMG" \ -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 echo echo "== Invalid snapshot L1 table size ==" @@ -193,6 +194,7 @@ poke_file "$TEST_IMG" "$offset_snap1_l1_size" "\x10\x00\x00\x00" { $QEMU_IO -c "open -o overlap-check.inactive-l2=on $TEST_IMG" \ -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 # success, all done echo "*** done" diff --git a/tests/qemu-iotests/080.out b/tests/qemu-iotests/080.out index 1525e1b..89bcd27 100644 --- a/tests/qemu-iotests/080.out +++ b/tests/qemu-iotests/080.out @@ -70,6 +70,7 @@ Failed to flush the refcount block cache: Invalid argument 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 == Invalid snapshot L1 table size == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 @@ -82,4 +83,5 @@ Failed to flush the refcount block cache: File too large 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 *** done |