summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Christopherson <seanjc@google.com>2025-08-08 10:23:57 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-10-29 13:59:54 +0100
commit1c572370fd0b14bc489388f73f93460c9a22179a (patch)
tree7849d161711cf93b8dd9815f8ebd6f72ce557c30
parentad5c71fa9b5ddc1e45f046fbef9bcd5fc5325c15 (diff)
downloadlinux-1c572370fd0b14bc489388f73f93460c9a22179a.tar.gz
linux-1c572370fd0b14bc489388f73f93460c9a22179a.tar.bz2
linux-1c572370fd0b14bc489388f73f93460c9a22179a.zip
x86/umip: Fix decoding of register forms of 0F 01 (SGDT and SIDT aliases)
commit 27b1fd62012dfe9d3eb8ecde344d7aa673695ecf upstream. Filter out the register forms of 0F 01 when determining whether or not to emulate in response to a potential UMIP violation #GP, as SGDT and SIDT only accept memory operands. The register variants of 0F 01 are used to encode instructions for things like VMX and SGX, i.e. not checking the Mod field would cause the kernel to incorrectly emulate on #GP, e.g. due to a CPL violation on VMLAUNCH. Fixes: 1e5db223696a ("x86/umip: Add emulation code for UMIP instructions") Signed-off-by: Sean Christopherson <seanjc@google.com> Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--arch/x86/kernel/umip.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/arch/x86/kernel/umip.c b/arch/x86/kernel/umip.c
index aadb819ed91b..b97323edb4f4 100644
--- a/arch/x86/kernel/umip.c
+++ b/arch/x86/kernel/umip.c
@@ -162,8 +162,19 @@ static int identify_insn(struct insn *insn)
if (insn->opcode.bytes[1] == 0x1) {
switch (X86_MODRM_REG(insn->modrm.value)) {
case 0:
+ /* The reg form of 0F 01 /0 encodes VMX instructions. */
+ if (X86_MODRM_MOD(insn->modrm.value) == 3)
+ return -EINVAL;
+
return UMIP_INST_SGDT;
case 1:
+ /*
+ * The reg form of 0F 01 /1 encodes MONITOR/MWAIT,
+ * STAC/CLAC, and ENCLS.
+ */
+ if (X86_MODRM_MOD(insn->modrm.value) == 3)
+ return -EINVAL;
+
return UMIP_INST_SIDT;
case 4:
return UMIP_INST_SMSW;