Skip to content

Commit a72c682

Browse files
pvts-matPlaidCat
authored andcommitted
x86/sev: Check for user-space IOIO pointing to kernel space
jira VULN-6719 cve CVE-2023-46813 commit-author Joerg Roedel <jroedel@suse.de> commit 63e44bc Check the memory operand of INS/OUTS before emulating the instruction. The #VC exception can get raised from user-space, but the memory operand can be manipulated to access kernel memory before the emulation actually begins and after the exception handler has run. [ bp: Massage commit message. ] Fixes: 597cfe4 ("x86/boot/compressed/64: Setup a GHCB-based VC Exception handler") Reported-by: Tom Dohrmann <erbse.13@gmx.de> Signed-off-by: Joerg Roedel <jroedel@suse.de> Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> Cc: <stable@kernel.org> (cherry picked from commit 63e44bc) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
1 parent 88cf2d1 commit a72c682

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

arch/x86/boot/compressed/sev.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,11 @@ static enum es_result vc_ioio_check(struct es_em_ctxt *ctxt, u16 port, size_t si
108108
return ES_OK;
109109
}
110110

111+
static bool fault_in_kernel_space(unsigned long address)
112+
{
113+
return false;
114+
}
115+
111116
#undef __init
112117
#undef __pa
113118
#define __init

arch/x86/kernel/sev-shared.c

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -599,14 +599,36 @@ void __init do_vc_no_ghcb(struct pt_regs *regs, unsigned long exit_code)
599599
sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ);
600600
}
601601

602+
static enum es_result vc_insn_string_check(struct es_em_ctxt *ctxt,
603+
unsigned long address,
604+
bool write)
605+
{
606+
if (user_mode(ctxt->regs) && fault_in_kernel_space(address)) {
607+
ctxt->fi.vector = X86_TRAP_PF;
608+
ctxt->fi.error_code = X86_PF_USER;
609+
ctxt->fi.cr2 = address;
610+
if (write)
611+
ctxt->fi.error_code |= X86_PF_WRITE;
612+
613+
return ES_EXCEPTION;
614+
}
615+
616+
return ES_OK;
617+
}
618+
602619
static enum es_result vc_insn_string_read(struct es_em_ctxt *ctxt,
603620
void *src, char *buf,
604621
unsigned int data_size,
605622
unsigned int count,
606623
bool backwards)
607624
{
608625
int i, b = backwards ? -1 : 1;
609-
enum es_result ret = ES_OK;
626+
unsigned long address = (unsigned long)src;
627+
enum es_result ret;
628+
629+
ret = vc_insn_string_check(ctxt, address, false);
630+
if (ret != ES_OK)
631+
return ret;
610632

611633
for (i = 0; i < count; i++) {
612634
void *s = src + (i * data_size * b);
@@ -627,7 +649,12 @@ static enum es_result vc_insn_string_write(struct es_em_ctxt *ctxt,
627649
bool backwards)
628650
{
629651
int i, s = backwards ? -1 : 1;
630-
enum es_result ret = ES_OK;
652+
unsigned long address = (unsigned long)dst;
653+
enum es_result ret;
654+
655+
ret = vc_insn_string_check(ctxt, address, true);
656+
if (ret != ES_OK)
657+
return ret;
631658

632659
for (i = 0; i < count; i++) {
633660
void *d = dst + (i * data_size * s);

0 commit comments

Comments
 (0)