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/3a5c7cc014f2
branches: trunk
changeset: 997990:3a5c7cc014f2
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 830491fd7b70 -r 3a5c7cc014f2 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 830491fd7b70 -r 3a5c7cc014f2 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 830491fd7b70 -r 3a5c7cc014f2 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 830491fd7b70 -r 3a5c7cc014f2 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