Skip to content

Commit

Permalink
qcow2: Check snapshot L1 table in qcow2_snapshot_delete()
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Eric Blake <[email protected]>
Signed-off-by: Kevin Wolf <[email protected]>
  • Loading branch information
bertogg authored and kevmw committed Mar 9, 2018
1 parent a8475d7 commit db5794f
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 0 deletions.
7 changes: 7 additions & 0 deletions block/qcow2-snapshot.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions tests/qemu-iotests/080
Original file line number Diff line number Diff line change
Expand Up @@ -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 =="
Expand All @@ -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"
Expand Down
2 changes: 2 additions & 0 deletions tests/qemu-iotests/080.out
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

0 comments on commit db5794f

Please sign in to comment.