Blame SOURCES/0010-examples-vhost_scsi-move-to-safe-GPA-translation-API.patch

c7ffa4
From d34212ffb5e333a515f87b2f828606bc5690b8b3 Mon Sep 17 00:00:00 2001
c7ffa4
From: Maxime Coquelin <maxime.coquelin@redhat.com>
c7ffa4
Date: Mon, 23 Apr 2018 11:33:47 +0200
c7ffa4
Subject: [PATCH 10/11] examples/vhost_scsi: move to safe GPA translation API
c7ffa4
c7ffa4
This patch uses the new rte_vhost_va_from_guest_pa() API
c7ffa4
to ensure all the descriptor buffer is mapped contiguously
c7ffa4
in the application virtual address space.
c7ffa4
c7ffa4
As the application did not checked return of previous API,
c7ffa4
this patch just print an error if the buffer address isn't in
c7ffa4
the vhost memory regions or if it is scattered. Ideally, it
c7ffa4
should handle scattered buffers gracefully.
c7ffa4
c7ffa4
This issue has been assigned CVE-2018-1059.
c7ffa4
c7ffa4
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
c7ffa4
---
c7ffa4
 examples/vhost_scsi/vhost_scsi.c | 56 +++++++++++++++++++++++++++++++++-------
c7ffa4
 1 file changed, 47 insertions(+), 9 deletions(-)
c7ffa4
c7ffa4
diff --git a/examples/vhost_scsi/vhost_scsi.c b/examples/vhost_scsi/vhost_scsi.c
c7ffa4
index b4f1f8d..b40f993 100644
c7ffa4
--- a/examples/vhost_scsi/vhost_scsi.c
c7ffa4
+++ b/examples/vhost_scsi/vhost_scsi.c
c7ffa4
@@ -69,5 +69,5 @@
c7ffa4
 }
c7ffa4
 
c7ffa4
-static uint64_t gpa_to_vva(int vid, uint64_t gpa)
c7ffa4
+static uint64_t gpa_to_vva(int vid, uint64_t gpa, uint64_t *len)
c7ffa4
 {
c7ffa4
 	char path[PATH_MAX];
c7ffa4
@@ -89,5 +89,5 @@ static uint64_t gpa_to_vva(int vid, uint64_t gpa)
c7ffa4
 	assert(ctrlr->mem != NULL);
c7ffa4
 
c7ffa4
-	return rte_vhost_gpa_to_vva(ctrlr->mem, gpa);
c7ffa4
+	return rte_vhost_va_from_guest_pa(ctrlr->mem, gpa, len);
c7ffa4
 }
c7ffa4
 
c7ffa4
@@ -139,13 +139,27 @@ static uint64_t gpa_to_vva(int vid, uint64_t gpa)
c7ffa4
 {
c7ffa4
 	void *data;
c7ffa4
+	uint64_t chunck_len;
c7ffa4
 
c7ffa4
 	task->iovs_cnt = 0;
c7ffa4
+	chunck_len = task->desc->len;
c7ffa4
 	task->resp = (void *)(uintptr_t)gpa_to_vva(task->bdev->vid,
c7ffa4
-						   task->desc->addr);
c7ffa4
+						   task->desc->addr,
c7ffa4
+						   &chunck_len);
c7ffa4
+	if (!task->resp || chunck_len != task->desc->len) {
c7ffa4
+		fprintf(stderr, "failed to translate desc address.\n");
c7ffa4
+		return;
c7ffa4
+	}
c7ffa4
 
c7ffa4
 	while (descriptor_has_next(task->desc)) {
c7ffa4
 		task->desc = descriptor_get_next(task->vq->desc, task->desc);
c7ffa4
+		chunck_len = task->desc->len;
c7ffa4
 		data = (void *)(uintptr_t)gpa_to_vva(task->bdev->vid,
c7ffa4
-						     task->desc->addr);
c7ffa4
+						     task->desc->addr,
c7ffa4
+							 &chunck_len);
c7ffa4
+		if (!data || chunck_len != task->desc->len) {
c7ffa4
+			fprintf(stderr, "failed to translate desc address.\n");
c7ffa4
+			return;
c7ffa4
+		}
c7ffa4
+
c7ffa4
 		task->iovs[task->iovs_cnt].iov_base = data;
c7ffa4
 		task->iovs[task->iovs_cnt].iov_len = task->desc->len;
c7ffa4
@@ -159,10 +173,18 @@ static uint64_t gpa_to_vva(int vid, uint64_t gpa)
c7ffa4
 {
c7ffa4
 	void *data;
c7ffa4
+	uint64_t chunck_len;
c7ffa4
 
c7ffa4
 	task->iovs_cnt = 0;
c7ffa4
 
c7ffa4
 	do {
c7ffa4
+		chunck_len = task->desc->len;
c7ffa4
 		data = (void *)(uintptr_t)gpa_to_vva(task->bdev->vid,
c7ffa4
-						     task->desc->addr);
c7ffa4
+						     task->desc->addr,
c7ffa4
+							 &chunck_len);
c7ffa4
+		if (!data || chunck_len != task->desc->len) {
c7ffa4
+			fprintf(stderr, "failed to translate desc address.\n");
c7ffa4
+			return;
c7ffa4
+		}
c7ffa4
+
c7ffa4
 		task->iovs[task->iovs_cnt].iov_base = data;
c7ffa4
 		task->iovs[task->iovs_cnt].iov_len = task->desc->len;
c7ffa4
@@ -172,6 +194,10 @@ static uint64_t gpa_to_vva(int vid, uint64_t gpa)
c7ffa4
 	} while (descriptor_has_next(task->desc));
c7ffa4
 
c7ffa4
+	chunck_len = task->desc->len;
c7ffa4
 	task->resp = (void *)(uintptr_t)gpa_to_vva(task->bdev->vid,
c7ffa4
-						   task->desc->addr);
c7ffa4
+						   task->desc->addr,
c7ffa4
+						   &chunck_len);
c7ffa4
+	if (!task->resp || chunck_len != task->desc->len)
c7ffa4
+		fprintf(stderr, "failed to translate desc address.\n");
c7ffa4
 }
c7ffa4
 
c7ffa4
@@ -219,4 +245,5 @@ static uint64_t gpa_to_vva(int vid, uint64_t gpa)
c7ffa4
 		uint16_t last_idx;
c7ffa4
 		struct vhost_scsi_task *task;
c7ffa4
+		uint64_t chunck_len;
c7ffa4
 
c7ffa4
 		last_idx = scsi_vq->last_used_idx & (vq->size - 1);
c7ffa4
@@ -236,14 +263,25 @@ static uint64_t gpa_to_vva(int vid, uint64_t gpa)
c7ffa4
 		scsi_vq->last_used_idx++;
c7ffa4
 
c7ffa4
+		chunck_len = task->desc->len;
c7ffa4
 		task->req = (void *)(uintptr_t)gpa_to_vva(task->bdev->vid,
c7ffa4
-							  task->desc->addr);
c7ffa4
+							  task->desc->addr,
c7ffa4
+							  &chunck_len);
c7ffa4
+		if (!task->req || chunck_len != task->desc->len) {
c7ffa4
+			fprintf(stderr, "failed to translate desc address.\n");
c7ffa4
+			return;
c7ffa4
+		}
c7ffa4
 
c7ffa4
 		task->desc = descriptor_get_next(task->vq->desc, task->desc);
c7ffa4
 		if (!descriptor_has_next(task->desc)) {
c7ffa4
 			task->dxfer_dir = SCSI_DIR_NONE;
c7ffa4
+			chunck_len = task->desc->len;
c7ffa4
 			task->resp = (void *)(uintptr_t)
c7ffa4
 					      gpa_to_vva(task->bdev->vid,
c7ffa4
-							 task->desc->addr);
c7ffa4
-
c7ffa4
+							 task->desc->addr,
c7ffa4
+							 &chunck_len);
c7ffa4
+			if (!task->resp || chunck_len != task->desc->len) {
c7ffa4
+				fprintf(stderr, "failed to translate desc address.\n");
c7ffa4
+				return;
c7ffa4
+			}
c7ffa4
 		} else if (!descriptor_is_wr(task->desc)) {
c7ffa4
 			task->dxfer_dir = SCSI_DIR_TO_DEV;
c7ffa4
-- 
c7ffa4
1.8.3.1
c7ffa4