Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/umip: Fix decoding of register forms of 0F 01 (SGDT and SIDT aliases)

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

authored by

Sean Christopherson and committed by
Borislav Petkov (AMD)
27b1fd62 32278c67

+11
+11
arch/x86/kernel/umip.c
··· 163 163 if (insn->opcode.bytes[1] == 0x1) { 164 164 switch (X86_MODRM_REG(insn->modrm.value)) { 165 165 case 0: 166 + /* The reg form of 0F 01 /0 encodes VMX instructions. */ 167 + if (X86_MODRM_MOD(insn->modrm.value) == 3) 168 + return -EINVAL; 169 + 166 170 return UMIP_INST_SGDT; 167 171 case 1: 172 + /* 173 + * The reg form of 0F 01 /1 encodes MONITOR/MWAIT, 174 + * STAC/CLAC, and ENCLS. 175 + */ 176 + if (X86_MODRM_MOD(insn->modrm.value) == 3) 177 + return -EINVAL; 178 + 168 179 return UMIP_INST_SIDT; 169 180 case 4: 170 181 return UMIP_INST_SMSW;