From: Joerg Roedel <jroe...@suse.de>

When a #VC exception is triggered by user-space the instruction
decoder needs to read the instruction bytes from user addresses.
Enhance es_fetch_insn_byte() to safely fetch kernel and user
instruction bytes.

Signed-off-by: Joerg Roedel <jroe...@suse.de>
---
 arch/x86/kernel/sev-es.c | 30 +++++++++++++++++++++++-------
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/arch/x86/kernel/sev-es.c b/arch/x86/kernel/sev-es.c
index 2a801919e7c0..f5bff4219f6f 100644
--- a/arch/x86/kernel/sev-es.c
+++ b/arch/x86/kernel/sev-es.c
@@ -61,13 +61,29 @@ static enum es_result es_fetch_insn_byte(struct es_em_ctxt 
*ctxt,
                                         unsigned int offset,
                                         char *buffer)
 {
-       char *rip = (char *)ctxt->regs->ip;
-
-       /* More checks are needed when we boot to user-space */
-       if (!check_kernel(ctxt->regs))
-               return ES_UNSUPPORTED;
-
-       buffer[offset] = rip[offset];
+       if (user_mode(ctxt->regs)) {
+               unsigned long addr = ctxt->regs->ip + offset;
+               char __user *rip = (char __user *)addr;
+
+               if (unlikely(addr >= TASK_SIZE_MAX))
+                       return ES_UNSUPPORTED;
+
+               if (copy_from_user(buffer + offset, rip, 1)) {
+                       ctxt->fi.vector     = X86_TRAP_PF;
+                       ctxt->fi.cr2        = addr;
+                       ctxt->fi.error_code = X86_PF_INSTR | X86_PF_USER;
+                       return ES_EXCEPTION;
+               }
+       } else {
+               char *rip = (char *)ctxt->regs->ip + offset;
+
+               if (probe_kernel_read(buffer + offset, rip, 1) != 0) {
+                       ctxt->fi.vector     = X86_TRAP_PF;
+                       ctxt->fi.cr2        = (unsigned long)rip;
+                       ctxt->fi.error_code = X86_PF_INSTR;
+                       return ES_EXCEPTION;
+               }
+       }
 
        return ES_OK;
 }
-- 
2.17.1

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Reply via email to