All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] KVM: x86: emulator: Fix illegal LEA handling
@ 2022-07-29 13:48 Michal Luczaj
  2022-07-29 13:48 ` [PATCH 2/2] KVM: selftests: x86: Test " Michal Luczaj
  2022-07-29 16:41 ` [PATCH 1/2] KVM: x86: emulator: Fix illegal LEA handling Sean Christopherson
  0 siblings, 2 replies; 22+ messages in thread
From: Michal Luczaj @ 2022-07-29 13:48 UTC (permalink / raw)
  To: kvm; +Cc: linux-kselftest, seanjc, pbonzini, shuah, Michal Luczaj

The emulator mishandles LEA with register source operand. Even though such
LEA is illegal, it can be encoded and fed to CPU. In which case real
hardware throws #UD. The emulator, instead, returns address of
x86_emulate_ctxt._regs. This info leak hurts host's kASLR.

Tell the decoder that illegal LEA is not to be emulated.

Signed-off-by: Michal Luczaj <mhal@rbox.co>
---
What the emulator does for LEA is simply:
	
	case 0x8d: /* lea r16/r32, m */
		ctxt->dst.val = ctxt->src.addr.mem.ea;
		break;

And it makes sense if you assume that LEA's source operand is always
memory. But because there is a race window between VM-exit and the decoder
instruction fetch, emulator can be force fed an arbitrary opcode of choice.
Including some that are simply illegal and would cause #UD in normal
circumstances. Such as a LEA with a register-direct source operand -- for
which the emulator sets `op->addr.reg`, but reads `op->addr.mem.ea`.

		union {
			unsigned long *reg;
			struct segmented_address {
				ulong ea;
				unsigned seg;
			} mem;
			...
		} addr;

Because `reg` and `mem` are in union, emulator reveals address in host's
memory.

I hope this patch is not considered an `instr_dual` abuse?

 arch/x86/kvm/emulate.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index f8382abe22ff..7c14706372d0 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -4566,6 +4566,10 @@ static const struct mode_dual mode_dual_63 = {
 	N, I(DstReg | SrcMem32 | ModRM | Mov, em_movsxd)
 };
 
+static const struct instr_dual instr_dual_8d = {
+	D(DstReg | SrcMem | ModRM | NoAccess), N
+};
+
 static const struct opcode opcode_table[256] = {
 	/* 0x00 - 0x07 */
 	F6ALU(Lock, em_add),
@@ -4622,7 +4626,7 @@ static const struct opcode opcode_table[256] = {
 	I2bv(DstMem | SrcReg | ModRM | Mov | PageTable, em_mov),
 	I2bv(DstReg | SrcMem | ModRM | Mov, em_mov),
 	I(DstMem | SrcNone | ModRM | Mov | PageTable, em_mov_rm_sreg),
-	D(ModRM | SrcMem | NoAccess | DstReg),
+	ID(0, &instr_dual_8d),
 	I(ImplicitOps | SrcMem16 | ModRM, em_mov_sreg_rm),
 	G(0, group1A),
 	/* 0x90 - 0x97 */
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2022-08-06 11:08 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-29 13:48 [PATCH 1/2] KVM: x86: emulator: Fix illegal LEA handling Michal Luczaj
2022-07-29 13:48 ` [PATCH 2/2] KVM: selftests: x86: Test " Michal Luczaj
2022-07-29 16:53   ` Sean Christopherson
2022-07-31 20:43     ` Michal Luczaj
2022-07-31 20:46     ` [kvm-unit-tests PATCH v2] " Michal Luczaj
2022-08-01 16:44       ` Sean Christopherson
2022-08-02 23:07         ` Michal Luczaj
2022-08-02 23:41           ` Sean Christopherson
2022-08-03 17:21             ` Michal Luczaj
2022-08-03 17:25             ` [kvm-unit-tests PATCH 1/4] x86: emulator.c cleanup: Save and restore exception handlers Michal Luczaj
2022-08-03 17:25               ` [kvm-unit-tests PATCH 2/4] x86: emulator.c cleanup: Use ASM_TRY for the UD_VECTOR cases Michal Luczaj
2022-08-03 18:21                 ` Sean Christopherson
2022-08-05 11:42                   ` Paolo Bonzini
2022-08-05 18:55                     ` Michal Luczaj
2022-08-05 19:59                       ` Sean Christopherson
2022-08-06  2:00                         ` Nadav Amit
2022-08-06 11:08                           ` Michal Luczaj
2022-08-03 17:25               ` [kvm-unit-tests PATCH 3/4] x86: Test emulator's handling of LEA with /reg Michal Luczaj
2022-08-03 17:25               ` [kvm-unit-tests PATCH 4/4] x86: Extend ASM_TRY to handle #UD thrown by FEP-triggered emulator Michal Luczaj
2022-08-03 18:16                 ` Sean Christopherson
2022-08-05 11:50                   ` Paolo Bonzini
2022-07-29 16:41 ` [PATCH 1/2] KVM: x86: emulator: Fix illegal LEA handling Sean Christopherson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.