[PATCH v3 6/7] x86/tdx: Add a restriction on access to MMIO address
From: Alexey Gladkov (Intel)
Date: Thu Aug 08 2024 - 11:44:47 EST
In the case of userspace MMIO, if the user instruction + MAX_INSN_SIZE
straddles page, then the "fetch" in the kernel could trigger a #VE. In
this case the kernel would handle this second #VE as a !user_mode() MMIO.
That way, additional address verifications can be avoided.
The scenario of accessing userspace MMIO addresses from kernelspace does
not seem appropriate under normal circumstances. Until there is a
specific usecase for such a scenario it can be disabled.
Signed-off-by: Alexey Gladkov (Intel) <legion@xxxxxxxxxx>
---
arch/x86/coco/tdx/tdx.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
index dfadb085d2d3..5b3421a89998 100644
--- a/arch/x86/coco/tdx/tdx.c
+++ b/arch/x86/coco/tdx/tdx.c
@@ -411,6 +411,11 @@ static inline bool is_private_gpa(u64 gpa)
return gpa == cc_mkenc(gpa);
}
+static inline bool is_kernel_addr(unsigned long addr)
+{
+ return (long)addr < 0;
+}
+
static int get_phys_addr(unsigned long addr, phys_addr_t *phys_addr, bool *writable)
{
unsigned int level;
@@ -641,6 +646,7 @@ static int handle_mmio(struct pt_regs *regs, struct ve_info *ve)
unsigned long vaddr;
int size, ret;
+
ret = decode_insn_struct(&insn, regs);
if (ret)
return ret;
@@ -661,6 +667,9 @@ static int handle_mmio(struct pt_regs *regs, struct ve_info *ve)
ret = valid_vaddr(ve, mmio, size, vaddr);
if (ret)
goto unlock;
+ } else if (!is_kernel_addr(ve->gla)) {
+ WARN_ONCE(1, "Access to userspace address is not supported");
+ return -EINVAL;
}
/*
--
2.45.2