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

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