1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
--- a/vmmon/Makefile
+++ b/vmmon/Makefile
@@ -43,7 +43,11 @@ INCLUDE += -I$(SRCROOT)/shared
endif
+ifdef KVERSION
+VM_UNAME = $(KVERSION)
+else
VM_UNAME = $(shell uname -r)
+endif
# Header directory for the running kernel
ifdef LINUXINCLUDE
@@ -137,7 +137,7 @@
endif
# Add Spectre options when available
-CC_OPTS += $(call vm_check_gcc,-mindirect-branch=thunk -mindirect-branch-register,)
+CC_OPTS += $(call vm_check_gcc,-mindirect-branch-register,)
include $(SRCROOT)/Makefile.kernel
From 2da85cbe6d9c0bc5c7c2008748bd12e70ce0f310 Mon Sep 17 00:00:00 2001
From: Jan Andres <jandres@gmx.net>
Date: Fri, 4 Sep 2020 10:53:10 +0200
Subject: [PATCH] Fix NX bit handling for Linux 5.8+
Do not use vmap() to map the cross page, it needs to be executable and
vmap() unconditionally sets the NX bit starting with 5.8.x.
Emulate previous behavior of vmap() by using alloc_vm_area() and
explicitly setting the PTE.
---
vmmon-only/linux/hostif.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/vmmon-only/linux/hostif.c b/vmmon-only/linux/hostif.c
index 3a48505..ec6856a 100644
--- a/vmmon-only/linux/hostif.c
+++ b/vmmon-only/linux/hostif.c
@@ -47,6 +47,7 @@
#include <asm/asm.h>
#include <asm/io.h>
#include <asm/page.h>
+#include <asm/tlbflush.h>
#include <asm/uaccess.h>
#include <linux/capability.h>
#include <linux/kthread.h>
@@ -634,7 +635,24 @@ HostIF_FastClockUnlock(int callerID) // IN
static void *
MapCrossPage(struct page *p) // IN:
{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)
return vmap(&p, 1, VM_MAP, VM_PAGE_KERNEL_EXEC);
+#else
+ /* Starting with 5.8, vmap() always sets the NX bit, but the cross
+ * page needs to be executable. */
+ pte_t *ptes[1];
+ struct vm_struct *area = alloc_vm_area(1UL << PAGE_SHIFT, ptes);
+ if (area == NULL)
+ return NULL;
+
+ set_pte(ptes[0], mk_pte(p, VM_PAGE_KERNEL_EXEC));
+
+ preempt_disable();
+ __flush_tlb_all();
+ preempt_enable();
+
+ return area->addr;
+#endif
}
From c71e377757f20dc78a99d42a127124bb2c49e865 Mon Sep 17 00:00:00 2001
From: Jan Andres <jandres@gmx.net>
Date: Fri, 4 Sep 2020 10:59:19 +0200
Subject: [PATCH] Fix NULL pointer dereference in eventfd read call
Starting with 5.8, the "read" function pointer in eventfd's
file_operations is NULL, "read_iter" is available instead.
Use kernel_read() and kernel_write() instead of directly calling the
function pointers to handle this correctly.
---
vmmon-only/linux/hostif.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/vmmon-only/linux/hostif.c b/vmmon-only/linux/hostif.c
index ec6856a..4a7afb1 100644
--- a/vmmon-only/linux/hostif.c
+++ b/vmmon-only/linux/hostif.c
@@ -2609,7 +2609,11 @@ HostIF_SemaphoreWait(VMDriver *vm, // IN:
* reading no bytes (EAGAIN - non blocking fd) or sizeof(uint64).
*/
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
+ res = kernel_read(file, (char *) &value, sizeof value, &file->f_pos);
+#else
res = file->f_op->read(file, (char *) &value, sizeof value, &file->f_pos);
+#endif
if (res == sizeof value) {
res = MX_WAITNORMAL;
@@ -2726,7 +2730,11 @@ HostIF_SemaphoreSignal(uint64 *args) // IN:
* it be present.
*/
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
+ res = kernel_write(file, (char *) &value, sizeof value, &file->f_pos);
+#else
res = file->f_op->write(file, (char *) &value, sizeof value, &file->f_pos);
+#endif
if (res == sizeof value) {
res = MX_WAITNORMAL;
|