From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51209) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aGU5N-0007CF-RZ for qemu-devel@nongnu.org; Tue, 05 Jan 2016 11:03:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aGU5K-0002sj-L0 for qemu-devel@nongnu.org; Tue, 05 Jan 2016 11:03:49 -0500 Received: from e06smtp15.uk.ibm.com ([195.75.94.111]:43545) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aGU5K-0002sa-CQ for qemu-devel@nongnu.org; Tue, 05 Jan 2016 11:03:46 -0500 Received: from localhost by e06smtp15.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 5 Jan 2016 16:03:44 -0000 Received: from b06cxnps4074.portsmouth.uk.ibm.com (d06relay11.portsmouth.uk.ibm.com [9.149.109.196]) by d06dlp01.portsmouth.uk.ibm.com (Postfix) with ESMTP id D6B3117D8056 for ; Tue, 5 Jan 2016 16:04:26 +0000 (GMT) Received: from d06av06.portsmouth.uk.ibm.com (d06av06.portsmouth.uk.ibm.com [9.149.37.217]) by b06cxnps4074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u05G3gFt10617102 for ; Tue, 5 Jan 2016 16:03:42 GMT Received: from d06av06.portsmouth.uk.ibm.com (localhost [127.0.0.1]) by d06av06.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id u05G3fnU009086 for ; Tue, 5 Jan 2016 09:03:41 -0700 From: Pierre Morel Date: Tue, 5 Jan 2016 17:03:40 +0100 Message-Id: <1452009820-24968-1-git-send-email-pmorel@linux.vnet.ibm.com> Subject: [Qemu-devel] [PATCH v2] vfio/common: Check iova with limit not with size List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: alex.williamson@redhat.com Cc: pbonzini@redhat.com, qemu-devel@nongnu.org, peter.maydell@linaro.org In vfio_listener_region_add(), the code makes sure that the offset in the section is lower than the size of the section. But the calculation uses size of the region instead of 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 --- hw/vfio/common.c | 15 ++++++++++----- 1 files changed, 10 insertions(+), 5 deletions(-) diff --git a/hw/vfio/common.c b/hw/vfio/common.c index 6797208..fe4962a 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/common.c @@ -342,18 +342,23 @@ static void vfio_listener_region_add(MemoryListener *listener, iova = TARGET_PAGE_ALIGN(section->offset_within_address_space); llend = int128_make64(section->offset_within_address_space); - llend = int128_add(llend, section->size); + + if (int128_ge(llend, int128_2_64())) { + llend = int128_add(llend, int128_sub(section->size, int128_one())); + } else { + llend = int128_add(llend, section->size); + } llend = int128_and(llend, int128_exts64(TARGET_PAGE_MASK)); - if (int128_ge(int128_make64(iova), llend)) { + if (int128_gt(int128_make64(iova), llend)) { return; } end = int128_get64(llend); - 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 +368,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 -- 1.7.1