diff mbox

[v3] vfio/common: Check iova with limit not with size

Message ID 1452611505-25478-1-git-send-email-pmorel@linux.vnet.ibm.com
State New
Headers show

Commit Message

Pierre Morel Jan. 12, 2016, 3:11 p.m. UTC
In vfio_listener_region_add(), we try to validate that the region is not
zero sized and hasn't overflowed the addresses space.

But the calculation uses the size of the region instead of
using the region's limit (size - 1).

This leads to Int128 overflow when the region has
been initialized to UINT64_MAX because in this case
memory_region_init() transform the size from UINT64_MAX
to int128_2_64().

Let's really use the limit by sustracting one to the size
and take care to use the limit for functions using limit
and size to call functions which need size.

Signed-off-by: Pierre Morel <pmorel@linux.vnet.ibm.com>
---

Changes from v2:
    - all, just ignore v2, sorry about this,
      this is build after v1

Changes from v1:
    - adjust the tests by knowing we already substracted one to end.

 hw/vfio/common.c |   14 +++++++-------
 1 files changed, 7 insertions(+), 7 deletions(-)
diff mbox

Patch

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 6797208..a5f6643 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -348,12 +348,12 @@  static void vfio_listener_region_add(MemoryListener *listener,
     if (int128_ge(int128_make64(iova), llend)) {
         return;
     }
-    end = int128_get64(llend);
+    end = int128_get64(int128_sub(llend, int128_one()));
 
-    if ((iova < container->min_iova) || ((end - 1) > container->max_iova)) {
+    if ((iova < container->min_iova) || (end  > container->max_iova)) {
         error_report("vfio: IOMMU container %p can't map guest IOVA region"
                      " 0x%"HWADDR_PRIx"..0x%"HWADDR_PRIx,
-                     container, iova, end - 1);
+                     container, iova, end);
         ret = -EFAULT;
         goto fail;
     }
@@ -363,7 +363,7 @@  static void vfio_listener_region_add(MemoryListener *listener,
     if (memory_region_is_iommu(section->mr)) {
         VFIOGuestIOMMU *giommu;
 
-        trace_vfio_listener_region_add_iommu(iova, end - 1);
+        trace_vfio_listener_region_add_iommu(iova, end);
         /*
          * FIXME: We should do some checking to see if the
          * capabilities of the host VFIO IOMMU are adequate to model
@@ -394,13 +394,13 @@  static void vfio_listener_region_add(MemoryListener *listener,
             section->offset_within_region +
             (iova - section->offset_within_address_space);
 
-    trace_vfio_listener_region_add_ram(iova, end - 1, vaddr);
+    trace_vfio_listener_region_add_ram(iova, end, vaddr);
 
-    ret = vfio_dma_map(container, iova, end - iova, vaddr, section->readonly);
+    ret = vfio_dma_map(container, iova, end - iova + 1, vaddr, section->readonly);
     if (ret) {
         error_report("vfio_dma_map(%p, 0x%"HWADDR_PRIx", "
                      "0x%"HWADDR_PRIx", %p) = %d (%m)",
-                     container, iova, end - iova, vaddr, ret);
+                     container, iova, end - iova + 1, vaddr, ret);
         goto fail;
     }