Linux Kernel Selftest development
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox