Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libnvmm Check the GPA permissions too in the Assists, be...



details:   https://anonhg.NetBSD.org/src/rev/a4fb5d39f5ae
branches:  trunk
changeset: 840372:a4fb5d39f5ae
user:      maxv <maxv%NetBSD.org@localhost>
date:      Thu Apr 04 17:33:47 2019 +0000

description:
Check the GPA permissions too in the Assists, because it is possible that
the guest traps on a page the virtualizer marked as read-only (even if it
appears as read-write in the HVA).

diffstat:

 lib/libnvmm/libnvmm.3     |   8 +++++---
 lib/libnvmm/libnvmm.c     |  22 ++++++++++++++++++----
 lib/libnvmm/libnvmm_x86.c |  35 +++++++++++++++++++++++------------
 lib/libnvmm/nvmm.h        |   5 +++--
 4 files changed, 49 insertions(+), 21 deletions(-)

diffs (282 lines):

diff -r f9ac9251dd10 -r a4fb5d39f5ae lib/libnvmm/libnvmm.3
--- a/lib/libnvmm/libnvmm.3     Thu Apr 04 15:53:44 2019 +0000
+++ b/lib/libnvmm/libnvmm.3     Thu Apr 04 17:33:47 2019 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: libnvmm.3,v 1.12 2019/03/21 20:21:40 maxv Exp $
+.\"    $NetBSD: libnvmm.3,v 1.13 2019/04/04 17:33:47 maxv Exp $
 .\"
 .\" Copyright (c) 2018, 2019 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -27,7 +27,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd March 19, 2019
+.Dd April 4, 2019
 .Dt LIBNVMM 3
 .Os
 .Sh NAME
@@ -77,7 +77,7 @@
     "gvaddr_t gva" "gpaddr_t *gpa" "nvmm_prot_t *prot"
 .Ft int
 .Fn nvmm_gpa_to_hva "struct nvmm_machine *mach" "gpaddr_t gpa" \
-    "uintptr_t *hva"
+    "uintptr_t *hva" "nvmm_prot_t *prot"
 .Ft void
 .Fn nvmm_callbacks_register "const struct nvmm_callbacks *cbs"
 .Ft int
@@ -241,6 +241,8 @@
 .Fa gpa
 into a host virtual address returned in
 .Fa hva .
+The associated page premissions are returned in
+.Fa prot .
 .Fa gpa
 must be page-aligned.
 .Pp
diff -r f9ac9251dd10 -r a4fb5d39f5ae lib/libnvmm/libnvmm.c
--- a/lib/libnvmm/libnvmm.c     Thu Apr 04 15:53:44 2019 +0000
+++ b/lib/libnvmm/libnvmm.c     Thu Apr 04 17:33:47 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: libnvmm.c,v 1.7 2019/03/21 20:21:40 maxv Exp $ */
+/*     $NetBSD: libnvmm.c,v 1.8 2019/04/04 17:33:47 maxv Exp $ */
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -50,6 +50,7 @@
        gpaddr_t gpa;
        uintptr_t hva;
        size_t size;
+       nvmm_prot_t prot;
 } area_t;
 
 typedef LIST_HEAD(, __area) area_list_t;
@@ -83,11 +84,21 @@
 }
 
 static int
-__area_add(struct nvmm_machine *mach, uintptr_t hva, gpaddr_t gpa, size_t size)
+__area_add(struct nvmm_machine *mach, uintptr_t hva, gpaddr_t gpa, size_t size,
+    int prot)
 {
        area_list_t *areas = mach->areas;
+       nvmm_prot_t nprot;
        area_t *area;
 
+       nprot = 0;
+       if (prot & PROT_READ)
+               nprot |= NVMM_PROT_READ;
+       if (prot & PROT_WRITE)
+               nprot |= NVMM_PROT_WRITE;
+       if (prot & PROT_EXEC)
+               nprot |= NVMM_PROT_EXEC;
+
        if (!__area_isvalid(mach, hva, gpa, size)) {
                errno = EINVAL;
                return -1;
@@ -99,6 +110,7 @@
        area->gpa = gpa;
        area->hva = hva;
        area->size = size;
+       area->prot = nprot;
 
        LIST_INSERT_HEAD(areas, area, list);
 
@@ -383,7 +395,7 @@
                return -1;
        }
 
-       ret = __area_add(mach, hva, gpa, size);
+       ret = __area_add(mach, hva, gpa, size, prot);
        if (ret == -1)
                return -1;
 
@@ -477,7 +489,8 @@
  */
 
 int
-nvmm_gpa_to_hva(struct nvmm_machine *mach, gpaddr_t gpa, uintptr_t *hva)
+nvmm_gpa_to_hva(struct nvmm_machine *mach, gpaddr_t gpa, uintptr_t *hva,
+    nvmm_prot_t *prot)
 {
        area_list_t *areas = mach->areas;
        area_t *ent;
@@ -485,6 +498,7 @@
        LIST_FOREACH(ent, areas, list) {
                if (gpa >= ent->gpa && gpa < ent->gpa + ent->size) {
                        *hva = ent->hva + (gpa - ent->gpa);
+                       *prot = ent->prot;
                        return 0;
                }
        }
diff -r f9ac9251dd10 -r a4fb5d39f5ae lib/libnvmm/libnvmm_x86.c
--- a/lib/libnvmm/libnvmm_x86.c Thu Apr 04 15:53:44 2019 +0000
+++ b/lib/libnvmm/libnvmm_x86.c Thu Apr 04 17:33:47 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: libnvmm_x86.c,v 1.27 2019/03/07 15:47:34 maxv Exp $    */
+/*     $NetBSD: libnvmm_x86.c,v 1.28 2019/04/04 17:33:47 maxv Exp $    */
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -123,13 +123,14 @@
        gpaddr_t L2gpa, L1gpa;
        uintptr_t L2hva, L1hva;
        pte_32bit_t *pdir, pte;
+       nvmm_prot_t pageprot;
 
        /* We begin with an RWXU access. */
        *prot = NVMM_PROT_ALL;
 
        /* Parse L2. */
        L2gpa = (cr3 & CR3_FRAME_32BIT);
-       if (nvmm_gpa_to_hva(mach, L2gpa, &L2hva) == -1)
+       if (nvmm_gpa_to_hva(mach, L2gpa, &L2hva, &pageprot) == -1)
                return -1;
        pdir = (pte_32bit_t *)L2hva;
        pte = pdir[pte32_l2idx(gva)];
@@ -149,7 +150,7 @@
 
        /* Parse L1. */
        L1gpa = (pte & PG_FRAME);
-       if (nvmm_gpa_to_hva(mach, L1gpa, &L1hva) == -1)
+       if (nvmm_gpa_to_hva(mach, L1gpa, &L1hva, &pageprot) == -1)
                return -1;
        pdir = (pte_32bit_t *)L1hva;
        pte = pdir[pte32_l1idx(gva)];
@@ -195,13 +196,14 @@
        gpaddr_t L3gpa, L2gpa, L1gpa;
        uintptr_t L3hva, L2hva, L1hva;
        pte_32bit_pae_t *pdir, pte;
+       nvmm_prot_t pageprot;
 
        /* We begin with an RWXU access. */
        *prot = NVMM_PROT_ALL;
 
        /* Parse L3. */
        L3gpa = (cr3 & CR3_FRAME_32BIT_PAE);
-       if (nvmm_gpa_to_hva(mach, L3gpa, &L3hva) == -1)
+       if (nvmm_gpa_to_hva(mach, L3gpa, &L3hva, &pageprot) == -1)
                return -1;
        pdir = (pte_32bit_pae_t *)L3hva;
        pte = pdir[pte32_pae_l3idx(gva)];
@@ -214,7 +216,7 @@
 
        /* Parse L2. */
        L2gpa = (pte & PG_FRAME);
-       if (nvmm_gpa_to_hva(mach, L2gpa, &L2hva) == -1)
+       if (nvmm_gpa_to_hva(mach, L2gpa, &L2hva, &pageprot) == -1)
                return -1;
        pdir = (pte_32bit_pae_t *)L2hva;
        pte = pdir[pte32_pae_l2idx(gva)];
@@ -234,7 +236,7 @@
 
        /* Parse L1. */
        L1gpa = (pte & PG_FRAME);
-       if (nvmm_gpa_to_hva(mach, L1gpa, &L1hva) == -1)
+       if (nvmm_gpa_to_hva(mach, L1gpa, &L1hva, &pageprot) == -1)
                return -1;
        pdir = (pte_32bit_pae_t *)L1hva;
        pte = pdir[pte32_pae_l1idx(gva)];
@@ -294,6 +296,7 @@
        gpaddr_t L4gpa, L3gpa, L2gpa, L1gpa;
        uintptr_t L4hva, L3hva, L2hva, L1hva;
        pte_64bit_t *pdir, pte;
+       nvmm_prot_t pageprot;
 
        /* We begin with an RWXU access. */
        *prot = NVMM_PROT_ALL;
@@ -303,7 +306,7 @@
 
        /* Parse L4. */
        L4gpa = (cr3 & CR3_FRAME_64BIT);
-       if (nvmm_gpa_to_hva(mach, L4gpa, &L4hva) == -1)
+       if (nvmm_gpa_to_hva(mach, L4gpa, &L4hva, &pageprot) == -1)
                return -1;
        pdir = (pte_64bit_t *)L4hva;
        pte = pdir[pte64_l4idx(gva)];
@@ -320,7 +323,7 @@
 
        /* Parse L3. */
        L3gpa = (pte & PG_FRAME);
-       if (nvmm_gpa_to_hva(mach, L3gpa, &L3hva) == -1)
+       if (nvmm_gpa_to_hva(mach, L3gpa, &L3hva, &pageprot) == -1)
                return -1;
        pdir = (pte_64bit_t *)L3hva;
        pte = pdir[pte64_l3idx(gva)];
@@ -340,7 +343,7 @@
 
        /* Parse L2. */
        L2gpa = (pte & PG_FRAME);
-       if (nvmm_gpa_to_hva(mach, L2gpa, &L2hva) == -1)
+       if (nvmm_gpa_to_hva(mach, L2gpa, &L2hva, &pageprot) == -1)
                return -1;
        pdir = (pte_64bit_t *)L2hva;
        pte = pdir[pte64_l2idx(gva)];
@@ -360,7 +363,7 @@
 
        /* Parse L1. */
        L1gpa = (pte & PG_FRAME);
-       if (nvmm_gpa_to_hva(mach, L1gpa, &L1hva) == -1)
+       if (nvmm_gpa_to_hva(mach, L1gpa, &L1hva, &pageprot) == -1)
                return -1;
        pdir = (pte_64bit_t *)L1hva;
        pte = pdir[pte64_l1idx(gva)];
@@ -568,7 +571,7 @@
        }
        size -= remain;
 
-       ret = nvmm_gpa_to_hva(mach, gpa, &hva);
+       ret = nvmm_gpa_to_hva(mach, gpa, &hva, &prot);
        is_mmio = (ret == -1);
 
        if (is_mmio) {
@@ -578,6 +581,10 @@
                mem.size = size;
                (*__callbacks.mem)(&mem);
        } else {
+               if (__predict_false(!(prot & NVMM_PROT_READ))) {
+                       errno = EFAULT;
+                       return -1;
+               }
                memcpy(data, (uint8_t *)hva, size);
        }
 
@@ -618,7 +625,7 @@
        }
        size -= remain;
 
-       ret = nvmm_gpa_to_hva(mach, gpa, &hva);
+       ret = nvmm_gpa_to_hva(mach, gpa, &hva, &prot);
        is_mmio = (ret == -1);
 
        if (is_mmio) {
@@ -628,6 +635,10 @@
                mem.size = size;
                (*__callbacks.mem)(&mem);
        } else {
+               if (__predict_false(!(prot & NVMM_PROT_WRITE))) {
+                       errno = EFAULT;
+                       return -1;
+               }
                memcpy((uint8_t *)hva, data, size);
        }
 
diff -r f9ac9251dd10 -r a4fb5d39f5ae lib/libnvmm/nvmm.h
--- a/lib/libnvmm/nvmm.h        Thu Apr 04 15:53:44 2019 +0000
+++ b/lib/libnvmm/nvmm.h        Thu Apr 04 17:33:47 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvmm.h,v 1.6 2019/01/07 16:30:25 maxv Exp $    */
+/*     $NetBSD: nvmm.h,v 1.7 2019/04/04 17:33:47 maxv Exp $    */
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -92,7 +92,8 @@
 
 int nvmm_gva_to_gpa(struct nvmm_machine *, nvmm_cpuid_t, gvaddr_t, gpaddr_t *,
     nvmm_prot_t *);
-int nvmm_gpa_to_hva(struct nvmm_machine *, gpaddr_t, uintptr_t *);
+int nvmm_gpa_to_hva(struct nvmm_machine *, gpaddr_t, uintptr_t *,
+    nvmm_prot_t *);
 
 int nvmm_assist_io(struct nvmm_machine *, nvmm_cpuid_t, struct nvmm_exit *);
 int nvmm_assist_mem(struct nvmm_machine *, nvmm_cpuid_t, struct nvmm_exit *);



Home | Main Index | Thread Index | Old Index