[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <7a4c51f7ccd11c3197f05a1affd6fdbcfad6baad.1723807851.git.legion@kernel.org>
Date: Fri, 16 Aug 2024 15:43:58 +0200
From: Alexey Gladkov <legion@...nel.org>
To: linux-kernel@...r.kernel.org,
linux-coco@...ts.linux.dev
Cc: "Alexey Gladkov (Intel)" <legion@...nel.org>,
Thomas Gleixner <tglx@...utronix.de>,
Ingo Molnar <mingo@...hat.com>,
Borislav Petkov <bp@...en8.de>,
Dave Hansen <dave.hansen@...ux.intel.com>,
"H. Peter Anvin" <hpa@...or.com>,
"Kirill A. Shutemov" <kirill.shutemov@...ux.intel.com>,
Andrew Morton <akpm@...ux-foundation.org>,
Yuan Yao <yuan.yao@...el.com>,
Geert Uytterhoeven <geert@...ux-m68k.org>,
Yuntao Wang <ytcoode@...il.com>,
Kai Huang <kai.huang@...el.com>,
Baoquan He <bhe@...hat.com>,
Oleg Nesterov <oleg@...hat.com>,
cho@...rosoft.com,
decui@...rosoft.com,
John.Starks@...rosoft.com
Subject: [PATCH v3 08/10] x86/tdx: Add a restriction on access to MMIO address
From: "Alexey Gladkov (Intel)" <legion@...nel.org>
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@...nel.org>
---
arch/x86/coco/tdx/tdx.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
index e3d692342603..94541ee724db 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;
@@ -592,6 +597,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;
@@ -600,6 +606,11 @@ static int handle_mmio(struct pt_regs *regs, struct ve_info *ve)
if (WARN_ON_ONCE(mmio == INSN_MMIO_DECODE_FAILED))
return -EINVAL;
+ if (!user_mode(regs) && !is_kernel_addr(ve->gla)) {
+ WARN_ONCE(1, "Access to userspace address is not supported");
+ return -EINVAL;
+ }
+
vaddr = (unsigned long)insn_get_addr_ref(&insn, regs);
if (current->mm) {
--
2.45.2
Powered by blists - more mailing lists