qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: Lukas Tschoke <lukts330@gmail.com>
Cc: qemu-devel@nongnu.org, qemu-block@nongnu.org
Subject: Re: [PATCH for-8.0] block/vhdx: fix dynamic VHDX BAT corruption
Date: Tue, 11 Apr 2023 13:08:14 +0200	[thread overview]
Message-ID: <ZDU/nthNEPzUGcl3@redhat.com> (raw)
In-Reply-To: <6cfb6d6b-adc5-7772-c8a5-6bae9a0ad668@gmail.com>

Am 08.04.2023 um 00:11 hat Lukas Tschoke geschrieben:
> The corruption occurs when a BAT entry aligned to 4096 bytes is changed.
> 
> Specifically, the corruption occurs during the creation of the LOG Data
> Descriptor. The incorrect behavior involves copying 4088 bytes from the
> original 4096 bytes aligned offset to `tmp[8..4096]` and then copying
> the new value for the first BAT entry to the beginning `tmp[0..8]`.
> This results in all existing BAT entries inside the 4K region being
> incorrectly moved by 8 bytes and the last entry being lost.
> 
> This bug did not cause noticeable corruption when only sequentially
> writing once to an empty dynamic VHDX (e.g.
> using `qemu-img convert -O vhdx -o subformat=dynamic ...`), but it
> still resulted in invalid values for the (unused) Sector Bitmap BAT
> entries.
> 
> Importantly, this corruption would only become noticeable after the
> corrupted BAT is re-read from the file.
> 
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/727
> Signed-off-by: Lukas Tschoke <lukts330@gmail.com>

Thanks, applied to the block branch.

Reviewing this function was a bit confusing, but after understanding
what each variable means, your change is clearly fixing a local bug and
therefore an improvement.

But now I'm wondering if it's really right that we don't have to handle
the case where we write only a few bytes and therefore can have a
leading and a trailing part in the same log sector.

In fact, having everything in the same sector actually seems to be the
only case that really happens because vhdx_log_write_and_flush() is only
called with length = 8 and offset = bat_entry_offset, which is a
multiple of 8.

Most of the cases should be in the middle of the BAT. vhdx_log_write()
uses the leading_length != 0 code path for them. This reads the part
before the written entry from the image, replaces the entry itself, but
seems to leave the buffer uninitialised for everything after the entry.
So does that part get corrupted?

I suspect that while your patch fixes some cases, the function still
isn't entirely right.

Do you happen to have a simple reproducer using only qemu-io and
qemu-img for the case you fixed? If so, maybe it could be relatively
easily adjusted to cover these other cases, too.

Kevin



  reply	other threads:[~2023-04-11 11:09 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-07 22:11 [PATCH] block/vhdx: fix dynamic VHDX BAT corruption Lukas Tschoke
2023-04-11 11:08 ` Kevin Wolf [this message]
2023-04-11 11:28   ` [PATCH for-8.0] " Kevin Wolf

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=ZDU/nthNEPzUGcl3@redhat.com \
    --to=kwolf@redhat.com \
    --cc=lukts330@gmail.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).