From: Alberto Garcia <berto@igalia.com>
To: qemu-devel@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>, Alberto Garcia <berto@igalia.com>,
qemu-block@nongnu.org, Max Reitz <mreitz@redhat.com>
Subject: [PATCH for-5.1] qcow2: Don't open images with a backing file and the data-file-raw bit
Date: Wed, 15 Apr 2020 21:02:07 +0200 [thread overview]
Message-ID: <20200415190207.21118-1-berto@igalia.com> (raw)
Although we cannot create these images with qemu-img it is still
possible to do it using an external tool. QEMU should refuse to open
them until the data-file-raw bit is cleared with 'qemu-img check'.
Signed-off-by: Alberto Garcia <berto@igalia.com>
---
block/qcow2.c | 39 ++++++++++++++++++++++++++++++++++++++
tests/qemu-iotests/244 | 13 +++++++++++++
tests/qemu-iotests/244.out | 14 ++++++++++++++
3 files changed, 66 insertions(+)
diff --git a/block/qcow2.c b/block/qcow2.c
index b524b0c53f..fcc3810391 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -588,16 +588,49 @@ static void qcow2_add_check_result(BdrvCheckResult *out,
}
}
+static int qcow2_check_header(BlockDriverState *bs, BdrvCheckResult *result,
+ BdrvCheckMode fix)
+{
+ BDRVQcow2State *s = bs->opaque;
+ int ret;
+
+ if (bs->backing && data_file_is_raw(bs)) {
+ fprintf(stderr, "%s header: data-file-raw cannot be set "
+ "when there is a backing file.\n",
+ fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR in");
+ if (fix & BDRV_FIX_ERRORS) {
+ s->autoclear_features &= ~QCOW2_AUTOCLEAR_DATA_FILE_RAW;
+ ret = qcow2_update_header(bs);
+ if (ret < 0) {
+ result->check_errors++;
+ return ret;
+ }
+ result->corruptions_fixed++;
+ } else {
+ result->corruptions++;
+ }
+ }
+
+ return 0;
+}
+
static int coroutine_fn qcow2_co_check_locked(BlockDriverState *bs,
BdrvCheckResult *result,
BdrvCheckMode fix)
{
+ BdrvCheckResult header_res = {};
BdrvCheckResult snapshot_res = {};
BdrvCheckResult refcount_res = {};
int ret;
memset(result, 0, sizeof(*result));
+ ret = qcow2_check_header(bs, &header_res, fix);
+ qcow2_add_check_result(result, &header_res, false);
+ if (ret < 0) {
+ return ret;
+ }
+
ret = qcow2_check_read_snapshot_table(bs, &snapshot_res, fix);
if (ret < 0) {
qcow2_add_check_result(result, &snapshot_res, false);
@@ -1604,6 +1637,12 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
/* read the backing file name */
if (header.backing_file_offset != 0) {
+ if (data_file_is_raw(bs) && (!(flags & BDRV_O_CHECK))) {
+ error_setg(errp, "data-file-raw cannot be set when "
+ "there is a backing file");
+ ret = -EINVAL;
+ goto fail;
+ }
len = header.backing_file_size;
if (len > MIN(1023, s->cluster_size - header.backing_file_offset) ||
len >= sizeof(bs->backing_file)) {
diff --git a/tests/qemu-iotests/244 b/tests/qemu-iotests/244
index 2ec1815e6f..159941acd4 100755
--- a/tests/qemu-iotests/244
+++ b/tests/qemu-iotests/244
@@ -211,6 +211,19 @@ $QEMU_IMG amend -f $IMGFMT -o "data_file=blkdebug::$TEST_IMG.data" "$TEST_IMG"
$QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n -C "$TEST_IMG.src" "$TEST_IMG"
$QEMU_IMG compare -f $IMGFMT -F $IMGFMT "$TEST_IMG.src" "$TEST_IMG"
+echo
+echo "=== Using and repairing an image with backing file and the data_file_raw bit ==="
+echo
+
+# Create an image with a backing file and an external data file
+TEST_IMG_FILE="$TEST_IMG.base" _make_test_img 1M
+_make_test_img -o "data_file=$TEST_IMG.data" -b "$TEST_IMG.base"
+# Set 'data_file_raw' directly on the header (qemu-img amend won't let us)
+poke_file "$TEST_IMG" 95 "\x02"
+# Trying to open the image should produce an error
+$QEMU_IMG info "$TEST_IMG" 2>&1 | _filter_testdir
+_check_test_img -r all
+
# success, all done
echo "*** done"
rm -f $seq.full
diff --git a/tests/qemu-iotests/244.out b/tests/qemu-iotests/244.out
index 56329deb4b..cab367dfb5 100644
--- a/tests/qemu-iotests/244.out
+++ b/tests/qemu-iotests/244.out
@@ -128,4 +128,18 @@ Offset Length Mapped to File
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IMGFMT.data
Images are identical.
Images are identical.
+
+=== Using and repairing an image with backing file and the data_file_raw bit ===
+
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=1048576
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT.base data_file=TEST_DIR/t.IMGFMT.data
+qemu-img: Could not open 'TEST_DIR/t.qcow2': data-file-raw cannot be set when there is a backing file
+Repairing header: data-file-raw cannot be set when there is a backing file.
+The following inconsistencies were found and repaired:
+
+ 0 leaked clusters
+ 1 corruptions
+
+Double checking the fixed image now...
+No errors were found on the image.
*** done
--
2.20.1
next reply other threads:[~2020-04-15 19:03 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-04-15 19:02 Alberto Garcia [this message]
2020-04-15 21:09 ` [PATCH for-5.1] qcow2: Don't open images with a backing file and the data-file-raw bit Eric Blake
2020-05-19 17:46 ` Alberto Garcia
2020-06-03 13:53 ` Max Reitz
2020-06-05 11:14 ` Kevin Wolf
2020-06-05 12:11 ` Max Reitz
2020-06-05 13:00 ` Kevin Wolf
2020-06-05 14:38 ` Max Reitz
2020-06-18 12:03 ` Alberto Garcia
2020-06-19 7:57 ` Max Reitz
2020-06-19 11:06 ` Alberto Garcia
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200415190207.21118-1-berto@igalia.com \
--to=berto@igalia.com \
--cc=kwolf@redhat.com \
--cc=mreitz@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).