Blame SOURCES/0003-vhost-introduce-safe-API-for-GPA-translation.patch

c7ffa4
From 1fd1b4807bdabc32953e2591e06ac9331edee76e Mon Sep 17 00:00:00 2001
c7ffa4
From: Maxime Coquelin <maxime.coquelin@redhat.com>
c7ffa4
Date: Mon, 23 Apr 2018 11:33:40 +0200
c7ffa4
Subject: [PATCH 03/11] vhost: introduce safe API for GPA translation
c7ffa4
c7ffa4
This new rte_vhost_va_from_guest_pa API takes an extra len
c7ffa4
parameter, used to specify the size of the range to be mapped.
c7ffa4
Effective mapped range is returned via len parameter.
c7ffa4
c7ffa4
This issue has been assigned CVE-2018-1059.
c7ffa4
c7ffa4
Reported-by: Yongji Xie <xieyongji@baidu.com>
c7ffa4
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
c7ffa4
---
c7ffa4
 lib/librte_vhost/rte_vhost.h           | 40 ++++++++++++++++++++++++++++++++++
c7ffa4
 lib/librte_vhost/rte_vhost_version.map |  6 +++++
c7ffa4
 lib/librte_vhost/vhost.h               |  2 +-
c7ffa4
 3 files changed, 47 insertions(+), 1 deletion(-)
c7ffa4
c7ffa4
diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
c7ffa4
index f653644..f2d6c95 100644
c7ffa4
--- a/lib/librte_vhost/rte_vhost.h
c7ffa4
+++ b/lib/librte_vhost/rte_vhost.h
c7ffa4
@@ -143,4 +143,44 @@ struct vhost_device_ops {
c7ffa4
 }
c7ffa4
 
c7ffa4
+/**
c7ffa4
+ * Convert guest physical address to host virtual address safely
c7ffa4
+ *
c7ffa4
+ * This variant of rte_vhost_gpa_to_vva() takes care all the
c7ffa4
+ * requested length is mapped and contiguous in process address
c7ffa4
+ * space.
c7ffa4
+ *
c7ffa4
+ * @param mem
c7ffa4
+ *  the guest memory regions
c7ffa4
+ * @param gpa
c7ffa4
+ *  the guest physical address for querying
c7ffa4
+ * @param len
c7ffa4
+ *  the size of the requested area to map, updated with actual size mapped
c7ffa4
+ * @return
c7ffa4
+ *  the host virtual address on success, 0 on failure
c7ffa4
+ */
c7ffa4
+static __rte_always_inline uint64_t
c7ffa4
+rte_vhost_va_from_guest_pa(struct rte_vhost_memory *mem,
c7ffa4
+						   uint64_t gpa, uint64_t *len)
c7ffa4
+{
c7ffa4
+	struct rte_vhost_mem_region *r;
c7ffa4
+	uint32_t i;
c7ffa4
+
c7ffa4
+	for (i = 0; i < mem->nregions; i++) {
c7ffa4
+		r = &mem->regions[i];
c7ffa4
+		if (gpa >= r->guest_phys_addr &&
c7ffa4
+		    gpa <  r->guest_phys_addr + r->size) {
c7ffa4
+
c7ffa4
+			if (unlikely(*len > r->guest_phys_addr + r->size - gpa))
c7ffa4
+				*len = r->guest_phys_addr + r->size - gpa;
c7ffa4
+
c7ffa4
+			return gpa - r->guest_phys_addr +
c7ffa4
+			       r->host_user_addr;
c7ffa4
+		}
c7ffa4
+	}
c7ffa4
+	*len = 0;
c7ffa4
+
c7ffa4
+	return 0;
c7ffa4
+}
c7ffa4
+
c7ffa4
 #define RTE_VHOST_NEED_LOG(features)	((features) & (1ULL << VHOST_F_LOG_ALL))
c7ffa4
 
c7ffa4
diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map
c7ffa4
index 1e70495..9cb1d8c 100644
c7ffa4
--- a/lib/librte_vhost/rte_vhost_version.map
c7ffa4
+++ b/lib/librte_vhost/rte_vhost_version.map
c7ffa4
@@ -53,2 +53,8 @@ DPDK_17.08 {
c7ffa4
 
c7ffa4
 } DPDK_17.05;
c7ffa4
+
c7ffa4
+DPDK_17.11.2 {
c7ffa4
+	global;
c7ffa4
+
c7ffa4
+	rte_vhost_va_from_guest_pa;
c7ffa4
+} DPDK_17.08;
c7ffa4
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
c7ffa4
index de300c1..16d6b89 100644
c7ffa4
--- a/lib/librte_vhost/vhost.h
c7ffa4
+++ b/lib/librte_vhost/vhost.h
c7ffa4
@@ -391,5 +391,5 @@ uint64_t __vhost_iova_to_vva(struct virtio_net *dev, struct vhost_virtqueue *vq,
c7ffa4
 {
c7ffa4
 	if (!(dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM)))
c7ffa4
-		return rte_vhost_gpa_to_vva(dev->mem, iova);
c7ffa4
+		return rte_vhost_va_from_guest_pa(dev->mem, iova, len);
c7ffa4
 
c7ffa4
 	return __vhost_iova_to_vva(dev, vq, iova, len, perm);
c7ffa4
-- 
c7ffa4
1.8.3.1
c7ffa4