|
|
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 |
|