All of lore.kernel.org
 help / color / mirror / Atom feed
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



             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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.