Public bug reported:

[Impact]

Users running VMs with `virtiofs` mounts where there is a page-size
mismatch between the host and guest kernels (e.g., a 4K page-size host
and a 64K page-size guest) experience "Cannot allocate memory"
(`ENOMEM`) errors when attempting to read directories.

This occurs because `virtiofsd` computes `max_pages` based on the host's
page size, but the guest converts `max_pages` back to bytes using its
own (larger) page size. As a result, the guest sends a `READDIR` request
that exceeds `virtiofsd`'s `MAX_BUFFER_SIZE`, causing the daemon to
reject the request.

The fix resolves this by capping the amount of directory data generated
locally to `MAX_BUFFER_SIZE` instead of rejecting the oversized request,
as `READDIR` is permitted to return fewer bytes than requested.

[Test Plan]

The Upstream MR has the details on how to reproduce and test the issue.
Replicating it here:

---
The virtiofsd-side failure is easiest to reproduce after applying the
kernel patch that backs uncached readdir output with pages: 
https://lore.kernel.org/all/[email protected]/
Without that kernel patch, the guest may fail earlier in the kernel before
the oversized READDIR request reaches virtiofsd.
The reproducer uses virtme-ng/vng: https://github.com/arighi/virtme-ng
Setup:

- Host: arm64 4K page-size kernel
- Guest: arm64 64K page-size kernel
- virtiofsd: unpatched
- vng: booting the guest with --overlay-rwdir /tmp

On the host, from the kernel build tree containing the 64K guest Image:

getconf PAGE_SIZE

vng --run arch/arm64/boot/Image \
  --memory 16G --cpus 4 --overlay-rwdir /tmp \
  --exec 'uname -r; getconf PAGE_SIZE; ls /tmp; echo "ls rc=$?"; python3 -c 
"import os; print(len(os.listdir(\"/tmp\")))"'

Expected with unpatched virtiofsd:

host PAGE_SIZE: 4096
guest PAGE_SIZE: 65536
ls: reading directory '/tmp': Cannot allocate memory
ls rc=2
OSError: [Errno 12] Cannot allocate memory: '/tmp'

With this virtiofsd patch applied, the same command succeeds.
The page-size mismatch is what exposes the issue. virtiofsd computes
max_pages from the host page size, while the guest converts max_pages back
to bytes using the guest page size. With a 4K host and 64K guest, the guest
can send a READDIR size larger than virtiofsd's MAX_BUFFER_SIZE.
READDIR can return less than requested, so this patch caps the amount of
directory data generated locally instead of rejecting the request.
---

[ Other Info ]

Target Releases: Ubuntu 24.04 and 26.04.

Upstream Commit: d24cda8a325d server: do not reject oversized readdir requests 
Upstream Link: 
https://gitlab.com/virtio-fs/virtiofsd/-/commit/d24cda8a325d2a9ae1adc5acda57515ed2e8e1d2
Upstream Merge Request: 
https://gitlab.com/virtio-fs/virtiofsd/-/merge_requests/316

** Affects: rust-virtiofsd (Ubuntu)
     Importance: Undecided
         Status: New

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2155048

Title:
  [SRU] Backport request - server: do not reject oversized readdir
  requests

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/rust-virtiofsd/+bug/2155048/+subscriptions


-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to