Skip to content

Commit

Permalink
qcow2: Don't open images with header.refcount_table_clusters == 0
Browse files Browse the repository at this point in the history
qcow2_do_open() is checking that header.refcount_table_clusters is not
too large, but it doesn't check that it's greater than zero. Apart
from the fact that an image like that is obviously corrupted, trying
to use it crashes QEMU since we end up with a null s->refcount_table
after qcow2_refcount_init().

These images can however be repaired, so allow opening them if the
BDRV_O_CHECK flag is set.

Signed-off-by: Alberto Garcia <[email protected]>
Reviewed-by: Max Reitz <[email protected]>
Message-id: f9750f50c80359babba11062e88f5075a47e8e16.1509718618.git.berto@igalia.com
Signed-off-by: Max Reitz <[email protected]>
  • Loading branch information
bertogg authored and XanClic committed Nov 14, 2017
1 parent 8aa3483 commit 951053a
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 0 deletions.
6 changes: 6 additions & 0 deletions block/qcow2.c
Original file line number Diff line number Diff line change
Expand Up @@ -1280,6 +1280,12 @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
goto fail;
}

if (header.refcount_table_clusters == 0 && !(flags & BDRV_O_CHECK)) {
error_setg(errp, "Image does not contain a reference count table");
ret = -EINVAL;
goto fail;
}

ret = validate_table_offset(bs, s->refcount_table_offset,
s->refcount_table_size, sizeof(uint64_t));
if (ret < 0) {
Expand Down
7 changes: 7 additions & 0 deletions tests/qemu-iotests/060
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,13 @@ poke_file "$TEST_IMG" "$rb_offset" "\x00\x00\x00\x00\x00\x00\x00\x00"
# write will try to allocate a compressed data cluster at offset 0.
$QEMU_IO -c "write -c 0k 64k" "$TEST_IMG" | _filter_qemu_io

echo
echo "=== Testing zero refcount table size ==="
echo
_make_test_img 64M
poke_file "$TEST_IMG" "56" "\x00\x00\x00\x00"
$QEMU_IO -c "write 0 64k" "$TEST_IMG" 2>&1 | _filter_testdir | _filter_imgfmt

# success, all done
echo "*** done"
rm -f $seq.full
Expand Down
5 changes: 5 additions & 0 deletions tests/qemu-iotests/060.out
Original file line number Diff line number Diff line change
Expand Up @@ -203,4 +203,9 @@ wrote 65536/65536 bytes at offset 65536
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qcow2: Marking image as corrupt: Preventing invalid allocation of compressed cluster at offset 0; further corruption events will be suppressed
write failed: Input/output error

=== Testing zero refcount table size ===

Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
can't open device TEST_DIR/t.IMGFMT: Image does not contain a reference count table
*** done

0 comments on commit 951053a

Please sign in to comment.