linux/drivers/vhost
Jun Yang 54617e9119 vhost: reset the vring metadata cache on vring reconfiguration
commit de845981da upstream.

vq->meta_iotlb[] caches the vhost_iotlb_map that backs each vring
metadata region, and iotlb_access_ok() returns early on a cache hit,
taking the hit as proof that the region has already been validated:

	if (vhost_vq_meta_fetch(vq, addr, len, type))
		return true;

The cache is reset on VHOST_IOTLB_UPDATE and VHOST_IOTLB_INVALIDATE, on
device IOTLB (re)initialisation and on vq reset, but not when
VHOST_SET_VRING_ADDR replaces vq->desc, vq->avail and vq->used, nor when
VHOST_SET_VRING_NUM changes the region sizes.

With a device IOTLB attached both ioctls are accepted while the vq is
live, and neither validates the addresses at ioctl time: vq_access_ok()
and vq_log_used_access_ok() return true early because the addresses are
GIOVAs, deferring validation to prefetch time.  Once the cache has been
populated that deferred validation no longer runs -- vq_meta_prefetch()
hits the stale entry and returns true -- and vhost_vq_meta_fetch() keeps
translating through the old mapping as

	map->addr + addr - map->start

for an address the mapping no longer covers.  vhost_copy_to_user() and
vhost_copy_from_user() consume the result with __copy_to_user() and
__copy_from_user(), which do not check it either, so a subsequent used
ring update or descriptor fetch accesses memory outside the region the
IOTLB actually maps.

Reset the metadata cache whenever the vring is reconfigured, so the new
addresses are pushed back through iotlb_access_ok()'s slow path.

Fixes: f889491380 ("vhost: introduce O(1) vq metadata cache")
Cc: stable@vger.kernel.org
Assisted-by: tencentos-corvus-ai:kimi-k3
Signed-off-by: Jun Yang <junvyyang@tencent.com>
Message-ID: <20260803014823.68623-1-juny24602@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
History 2026-08-19 17:14:17 +02:00
..
iotlb.c vhost: handle error while adding split ranges to iotlb 2022-04-08 14:24:12 +02:00
Kconfig vhost_vdpa: implement IRQ offloading in vhost_vdpa 2020-08-05 11:08:42 -04:00
Makefile vhost: introduce vDPA-based backend 2020-04-02 10:41:40 -04:00
net.c use less confusing names for iov_iter direction initializers 2026-06-19 13:33:46 +02:00
scsi.c use less confusing names for iov_iter direction initializers 2026-06-19 13:33:46 +02:00
test.c tools/virtio: Add --reset 2020-06-22 12:34:21 -04:00
test.h tools/virtio: Add --reset 2020-06-22 12:34:21 -04:00
vdpa.c vhost/vdpa: reject overflowing PA map page counts on 32-bit 2026-08-19 17:14:13 +02:00
vhost.c vhost: reset the vring metadata cache on vring reconfiguration 2026-08-19 17:14:17 +02:00
vhost.h vhost: support PACKED when setting-getting vring_base 2023-06-14 11:13:09 +02:00
vringh.c use less confusing names for iov_iter direction initializers 2026-06-19 13:33:46 +02:00
vsock.c use less confusing names for iov_iter direction initializers 2026-06-19 13:33:46 +02:00