qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Max Reitz <mreitz@redhat.com>
To: qemu-block@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
	qemu-devel@nongnu.org, Max Reitz <mreitz@redhat.com>
Subject: [Qemu-devel] [PULL 08/15] vmdk: Reject invalid compressed writes
Date: Tue, 27 Aug 2019 20:23:06 +0200	[thread overview]
Message-ID: <20190827182313.25983-9-mreitz@redhat.com> (raw)
In-Reply-To: <20190827182313.25983-1-mreitz@redhat.com>

Compressed writes generally have to write full clusters, not just in
theory but also in practice when it comes to vmdk's streamOptimized
subformat.  It currently is just silently broken for writes with
non-zero in-cluster offsets:

$ qemu-img create -f vmdk -o subformat=streamOptimized foo.vmdk 1M
$ qemu-io -c 'write 4k 4k' -c 'read 4k 4k' foo.vmdk
wrote 4096/4096 bytes at offset 4096
4 KiB, 1 ops; 00.01 sec (443.724 KiB/sec and 110.9309 ops/sec)
read failed: Invalid argument

(The technical reason is that vmdk_write_extent() just writes the
incomplete compressed data actually to offset 4k.  When reading the
data, vmdk_read_extent() looks at offset 0 and finds the compressed data
size to be 0, because that is what it reads from there.  This yields an
error.)

For incomplete writes with zero in-cluster offsets, the error path when
reading the rest of the cluster is a bit different, but the result is
the same:

$ qemu-img create -f vmdk -o subformat=streamOptimized foo.vmdk 1M
$ qemu-io -c 'write 0k 4k' -c 'read 4k 4k' foo.vmdk
wrote 4096/4096 bytes at offset 0
4 KiB, 1 ops; 00.01 sec (362.641 KiB/sec and 90.6603 ops/sec)
read failed: Invalid argument

(Here, vmdk_read_extent() finds the data and then sees that the
uncompressed data is short.)

It is better to reject invalid writes than to make the user believe they
might have succeeded and then fail when trying to read it back.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Message-id: 20190815153638.4600-5-mreitz@redhat.com
Reviewed-by: John Snow <jsnow@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
---
 block/vmdk.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/block/vmdk.c b/block/vmdk.c
index a7f82e665e..fed3b50c8a 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1734,6 +1734,16 @@ static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
     if (extent->compressed) {
         void *compressed_data;
 
+        /* Only whole clusters */
+        if (offset_in_cluster ||
+            n_bytes > (extent->cluster_sectors * SECTOR_SIZE) ||
+            (n_bytes < (extent->cluster_sectors * SECTOR_SIZE) &&
+             offset + n_bytes != extent->end_sector * SECTOR_SIZE))
+        {
+            ret = -EINVAL;
+            goto out;
+        }
+
         if (!extent->has_marker) {
             ret = -EINVAL;
             goto out;
-- 
2.21.0



  parent reply	other threads:[~2019-08-27 18:39 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-27 18:22 [Qemu-devel] [PULL 00/15] Block patches Max Reitz
2019-08-27 18:22 ` [Qemu-devel] [PULL 01/15] qemu-io: add pattern file for write command Max Reitz
2019-08-27 18:23 ` [Qemu-devel] [PULL 02/15] block: fix permission update in bdrv_replace_node Max Reitz
2019-08-27 18:23 ` [Qemu-devel] [PULL 03/15] block: posix: Always allocate the first block Max Reitz
2019-08-27 18:23 ` [Qemu-devel] [PULL 04/15] iotests: Test allocate_first_block() with O_DIRECT Max Reitz
2019-08-27 18:23 ` [Qemu-devel] [PULL 05/15] iotests: Fix _filter_img_create() Max Reitz
2019-08-27 18:23 ` [Qemu-devel] [PULL 06/15] vmdk: Use bdrv_dirname() for relative extent paths Max Reitz
2019-08-27 18:23 ` [Qemu-devel] [PULL 07/15] iotests: Keep testing broken " Max Reitz
2019-08-27 18:23 ` Max Reitz [this message]
2019-08-27 18:23 ` [Qemu-devel] [PULL 09/15] iotests: Disable broken streamOptimized tests Max Reitz
2019-08-27 18:23 ` [Qemu-devel] [PULL 10/15] iotests: Disable 110 for vmdk.twoGbMaxExtentSparse Max Reitz
2019-08-27 18:23 ` [Qemu-devel] [PULL 11/15] iotests: Disable 126 for flat vmdk subformats Max Reitz
2019-08-27 18:23 ` [Qemu-devel] [PULL 12/15] file-posix: fix request_alignment typo Max Reitz
2019-08-27 18:23 ` [Qemu-devel] [PULL 13/15] iotests: Check for enabled drivers before testing them Max Reitz
2019-08-27 18:23 ` [Qemu-devel] [PULL 14/15] tests/check-block: Skip iotests when sanitizers are enabled Max Reitz
2019-08-27 18:23 ` [Qemu-devel] [PULL 15/15] iotests: Unify cache mode quoting Max Reitz
2019-09-03  8:39 ` [Qemu-devel] [PULL 00/15] Block patches Peter Maydell
2019-09-03 12:50   ` Max Reitz

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=20190827182313.25983-9-mreitz@redhat.com \
    --to=mreitz@redhat.com \
    --cc=peter.maydell@linaro.org \
    --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).