All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michal Luczaj <mhal@rbox.co>
To: kvm@vger.kernel.org
Cc: linux-kselftest@vger.kernel.org, seanjc@google.com,
	pbonzini@redhat.com, shuah@kernel.org,
	Michal Luczaj <mhal@rbox.co>
Subject: [PATCH 1/2] KVM: x86: emulator: Fix illegal LEA handling
Date: Fri, 29 Jul 2022 15:48:01 +0200	[thread overview]
Message-ID: <20220729134801.1120-1-mhal@rbox.co> (raw)

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


             reply	other threads:[~2022-07-29 14:44 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-29 13:48 Michal Luczaj [this message]
2022-07-29 13:48 ` [PATCH 2/2] KVM: selftests: x86: Test illegal LEA handling 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220729134801.1120-1-mhal@rbox.co \
    --to=mhal@rbox.co \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=seanjc@google.com \
    --cc=shuah@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.