Re: [PATCH] vhost-user: check memory slot availability for SHMEM_MAP
Stefano Garzarella <[email protected]>
| Newsgroups | gmane.comp.emulators.qemu |
|---|---|
| Message-ID | <anSKEbnzeJQXFKqy@sgarzare-redhat> |
On Mon, Jul 20, 2026 at 05:36:37AM +0000, Feifan Qian wrote:
>SHMEM_MAP creates a separate RAM MemoryRegion for every mapping. It can
>therefore make a vhost-user memory table exceed the number of slots
>negotiated with the backend. The region reconciliation code then indexes
>fixed-size bookkeeping arrays past their end.
>
>Reject a mapping before changing the memory topology if KVM or a vhost
>backend has no unreserved slot left. Also validate each memory table
>against the negotiated vhost-user limit as a final defense for mappings
>that become visible in a later memory transaction.
>
>Fixes: b52e1896e764 ("vhost-user: Add VirtIO Shared Memory map request")
>Signed-off-by: Feifan Qian <[email protected]>
>---
>Tested with an ASan/UBSan x86_64 build and a vhost-user backend that
>mapped one-page SHMEM regions up to the 512-slot limit. The next
>SHMEM_MAP request was rejected and QEMU remained alive. Before this
>patch, the same reproducer reported an out-of-bounds write at found[512]
>in scrub_shadow_regions(). qtest-x86_64/qos-test also passed all 140
>subtests.
>
>hw/virtio/vhost-user.c | 18 ++++++++++++++++++
>1 file changed, 18 insertions(+)
This patch is corrupted:
$ git am ./20260720_bea1e_vhost_user_check_memory_slot_availability_for_shmem_map.mbx
Applying: vhost-user: check memory slot availability for SHMEM_MAP
error: corrupt patch at /home/stefano/repos/qemu/.git/worktrees/qemu-review/rebase-apply/patch:18
Patch failed at 0001 vhost-user: check memory slot availability for SHMEM_MAP
And the maintainer is not CCed:
$ ./scripts/get_maintainer.pl -f hw/virtio/vhost-user.c
"Michael S. Tsirkin" <[email protected]> (supporter:vhost, gitlab:@mstredhat)
Stefano Garzarella <[email protected]> (reviewer:vhost, gitlab:@sgarzarella)
[email protected] (open list:All patches CC here)
Please fix it.
Stefano
>
>diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
>index 517cc4ca71..7f141c116b 100644
>--- a/hw/virtio/vhost-user.c
>+++ b/hw/virtio/vhost-user.c
>@@ -10,6 +10,7 @@
>
>#include "qemu/osdep.h"
>#include "qapi/error.h"
>+#include "hw/mem/memory-device.h"
>#include "hw/virtio/virtio-dmabuf.h"
>#include "hw/virtio/virtio-qmp.h"
>#include "hw/virtio/vhost.h"
>@@ -1123,6 +1124,13 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev,
>dev, VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS);
>int ret;
>
>+ if (mem->nregions > u->user->memory_slots) {
>+ error_report("vhost-user memory table has %u regions, "
>+ "but the backend supports only %d",
>+ mem->nregions, u->user->memory_slots);
>+ return -ENOSPC;
>+ }
>+
>if (do_postcopy) {
>/*
>* Postcopy has enough differences that it's best done in it's own
>@@ -1937,6 +1945,7 @@ vhost_user_backend_handle_shmem_map(struct vhost_dev *dev,
>VhostUserMMap *vu_mmap = &payload->mmap;
>VirtioSharedMemoryMapping *existing;
>Error *local_err = NULL;
>+ unsigned int reserved_memslots;
>int ret = 0;
>
>if (fd < 0) {
>@@ -1977,6 +1986,15 @@ vhost_user_backend_handle_shmem_map(struct vhost_dev *dev,
>}
>}
>
>+ reserved_memslots = memory_devices_get_reserved_memslots();
>+ if ((kvm_enabled() &&
>+ kvm_get_free_memslots() <= reserved_memslots) ||
>+ vhost_get_free_memslots() <= reserved_memslots) {
>+ error_report("No free memory slots for shared memory mapping");
>+ ret = -ENOSPC;
>+ goto send_reply;
>+ }
>+
>memory_region_transaction_begin();
>
>/* Create VirtioSharedMemoryMapping object */
>--2.43.0