mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Hans de Goede <hansg@kernel.org>
To: Kentaro Shiomi <k.shiomi@techhowto.blog>,
	Jori Koolstra <jkoolstra@xs4all.nl>
Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] vboxsf: fix endless write loop and data corruption on short copy
Date: Sun, 20 Sep 2026 13:29:15 +0200	[thread overview]
Message-ID: <d64eabce-ebfb-45a6-9ef3-74280dc2c5a3@kernel.org> (raw)
In-Reply-To: <20260919174136.3325-1-k.shiomi@techhowto.blog>

+To: Jori Koolstra, who maintains vboxsf now.

Regards,

Hans

On 19-Sep-26 19:41, Kentaro Shiomi wrote:
> vboxsf_write_end() ignores the number of bytes that the generic write
> path managed to copy into the folio: it initialises nwritten with the
> requested length, writes that many bytes to the host and returns the
> requested length even when copied == 0.
> 
> generic_perform_write() then sees status != 0, so it never calls
> fault_in_iov_iter_readable(), advances pos by the full length and loops
> again with an iterator that has not been advanced at all.  The result is
> an endless loop that keeps appending zeroed data to the file (filling up
> the host file system) while flooding the log with
> 
>   WARNING: lib/iov_iter.c:624 at iov_iter_revert+0x1fc/0x270
> 
> because iov_iter_revert() is called with copied - status, i.e. a
> negative value.
> 
> The same accounting bug can silently corrupt data: when the folio is
> already uptodate, the stale part is not zeroed, so a short copy makes
> vboxsf write the old folio contents to the host and report success.
> 
> A short copy is not an error condition - it happens whenever the source
> pages are not faulted in yet, e.g. when writing directly from an mmap of
> another file or from shared memory (virtiofsd does exactly this).
> 
> Return the number of bytes that were actually copied, and reject the
> write entirely when nothing was copied so that the generic code faults
> the source pages in and retries.
> 
> Signed-off-by: Kentaro Shiomi <k.shiomi@techhowto.blog>
> ---
> Found while running a nested VM (QEMU/KVM) inside a VirtualBox guest: the
> virtiofsd instance exporting a directory that lives on a vboxsf mount writes
> straight from the shared guest memory, so the source pages are not faulted in
> and every write takes the short-copy path.  Creating a 6-byte text file grew
> the file to 29 KB within seconds and a small PNG reached 202 MB before the VM
> was killed; the guest ran out of disk space because ~16 GB of logs were
> written in the meantime.
> 
> Reproduced without virtiofsd or nested virtualisation by writing a few bytes
> to a vboxsf file from a PROT_READ mapping (memfd or another file) that has not
> been read yet: with the mapping touched first the write succeeds, without it
> the write never returns and only dies on SIGKILL.
> 
> Tested on Ubuntu 26.04.1 (6.x userspace, kernel 7.0.0-31-generic) as a guest of
> VirtualBox 7.2.16 on a Windows host.  With the patch applied, writes from
> non-faulted pages, partially copied writes and in-place rewrites all produce
> byte-identical files on the host, and the virtiofsd workload completes with no
> kernel warnings.
> 
> While investigating I also hit an unrelated NULL pointer dereference in
> vboxsf_release_sf_handle() when opening a vboxsf file with O_DIRECT; that one
> will be reported separately.
> 
> A DKMS package with this patch is available at
> https://github.com/kentaro-shiomi/virtualbox-vboxsf-endless-write-loop-fix
>  fs/vboxsf/file.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/vboxsf/file.c b/fs/vboxsf/file.c
> index 7a7a3fbb2..1e9f61883 100644
> --- a/fs/vboxsf/file.c
> +++ b/fs/vboxsf/file.c
> @@ -307,7 +307,7 @@ static int vboxsf_write_end(const struct kiocb *iocb,
>  	struct inode *inode = mapping->host;
>  	struct vboxsf_handle *sf_handle = iocb->ki_filp->private_data;
>  	size_t from = offset_in_folio(folio, pos);
> -	u32 nwritten = len;
> +	u32 nwritten = copied;
>  	u8 *buf;
>  	int err;
>  
> @@ -315,6 +315,10 @@ static int vboxsf_write_end(const struct kiocb *iocb,
>  	if (!folio_test_uptodate(folio) && copied < len)
>  		folio_zero_range(folio, from + copied, len - copied);
>  
> +	/* Nothing copied: reject so generic_perform_write() faults in and retries */
> +	if (!copied)
> +		goto out;
> +
>  	buf = kmap(&folio->page);
>  	err = vboxsf_write(sf_handle->root, sf_handle->handle,
>  			   pos, &nwritten, buf + from);


      reply	other threads:[~2026-09-20 11:29 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-19 17:41 Kentaro Shiomi
2026-09-20 11:29 ` Hans de Goede [this message]

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=d64eabce-ebfb-45a6-9ef3-74280dc2c5a3@kernel.org \
    --to=hansg@kernel.org \
    --cc=jkoolstra@xs4all.nl \
    --cc=k.shiomi@techhowto.blog \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.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

all inboxes | Powered by JetHome®