aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorHawkins Jiawei <yin31149@gmail.com>2023-07-07 23:27:31 +0800
committerMichael S. Tsirkin <mst@redhat.com>2023-07-10 18:59:32 -0400
commitb77a5f22aca4cef2dc893ea544841bdd95dc83ba (patch)
tree5319d41f7d1a3e12c736a2b73d66611559167e7d /hw
parentb12f907eeaad7bd4d282502bd7f7773f95e1ee96 (diff)
downloadqemu-b77a5f22aca4cef2dc893ea544841bdd95dc83ba.zip
qemu-b77a5f22aca4cef2dc893ea544841bdd95dc83ba.tar.gz
qemu-b77a5f22aca4cef2dc893ea544841bdd95dc83ba.tar.bz2
vhost: Fix false positive out-of-bounds
QEMU uses vhost_svq_translate_addr() to translate addresses between the QEMU's virtual address and the SVQ IOVA. In order to validate this translation, QEMU checks whether the translated range falls within the mapped range. Yet the problem is that, the value of `needle_last`, which is calculated by `needle.translated_addr + iovec[i].iov_len`, should represent the exclusive boundary of the translated range, rather than the last inclusive addresses of the range. Consequently, QEMU fails the check when the translated range matches the size of the mapped range. This patch solves this problem by fixing the `needle_last` value to the last inclusive address of the translated range. Note that this bug cannot be triggered at the moment, because QEMU is unable to translate such a big range due to the truncation of the CVQ command in vhost_vdpa_net_handle_ctrl_avail(). Fixes: 34e3c94eda ("vdpa: Add custom IOTLB translations to SVQ") Signed-off-by: Hawkins Jiawei <yin31149@gmail.com> Message-Id: <ee31c5420ffc8e6a29705ddd30badb814ddbae1d.1688743107.git.yin31149@gmail.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/virtio/vhost-shadow-virtqueue.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
index 1b1d853..49e5aed 100644
--- a/hw/virtio/vhost-shadow-virtqueue.c
+++ b/hw/virtio/vhost-shadow-virtqueue.c
@@ -111,7 +111,7 @@ static bool vhost_svq_translate_addr(const VhostShadowVirtqueue *svq,
addrs[i] = map->iova + off;
needle_last = int128_add(int128_make64(needle.translated_addr),
- int128_make64(iovec[i].iov_len));
+ int128_makes64(iovec[i].iov_len - 1));
map_last = int128_make64(map->translated_addr + map->size);
if (unlikely(int128_gt(needle_last, map_last))) {
qemu_log_mask(LOG_GUEST_ERROR,