Patch "KVM: x86: fix emulation of "MOV SS, null selector"" has been added to the 4.4-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
KVM: x86: fix emulation of "MOV SS, null selector"
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
kvm-x86-fix-emulation-of-mov-ss-null-selector.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
33ab91103b3415e12457e3104f0e4517ce12d0f3Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <[email protected]>
Date: Thu, 12 Jan 2017 15:02:32 +0100
Subject: KVM: x86: fix emulation of "MOV SS, null selector"
From: Paolo Bonzini <[email protected]>
commit 33ab91103b3415e12457e3104f0e4517ce12d0f3 upstream.
This is CVE-2017-2583. On Intel this causes a failed vmentry because SS's type is neither 3 nor 7 (even though the manual says this check is only done for usable SS, and the dmesg splat says that SS is unusable!). On AMD it's worse: svm.c is confused and sets CPL to 0 in the vmcb.
The fix fabricates a data segment descriptor when SS is set to a null selector, so that CPL and SS.DPL are set correctly in the VMCS/vmcb. Furthermore, only allow setting SS to a NULL selector if SS.RPL < 3; this in turn ensures CPL < 3 because RPL must be equal to CPL.
Thanks to Andy Lutomirski and Willy Tarreau for help in analyzing the bug and deciphering the manuals.
--- arch/x86/kvm/emulate.c | 48 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 10 deletions(-)
arch/x86/kvm/emulate.c +38 -10
@@ -1532,7 +1532,6 @@ static int write_segment_descriptor(stru &ctxt->exception); } -/* Does not support long mode */ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt, u16 selector, int seg, u8 cpl, enum x86_transfer_type transfer,
@@ -1569,20 +1568,34 @@ static int __load_segment_descriptor(str rpl = selector &3 ; -/* NULL selector is not valid for TR, CS and SS (except for long mode) */ -if ((seg ==VCPU_SREG_CS - || (seg ==VCPU_SREG_SS - && (ctxt->mode !=X86EMUL_MODE_PROT64 || rpl != cpl)) - || seg ==VCPU_SREG_TR ) - && null_selector) - goto exception; -/* TR should be in GDT only */ if (seg ==VCPU_SREG_TR && (selector & (1 <<2 ))) goto exception; -if (null_selector)/* for NULL selector skip all following checks */ +/* NULL selector is not valid for TR, CS and (except for long mode) SS */ +if (null_selector) { +if (seg ==VCPU_SREG_CS || seg ==VCPU_SREG_TR ) + goto exception; + +if (seg ==VCPU_SREG_SS ) { +if (ctxt->mode !=X86EMUL_MODE_PROT64 || rpl != cpl) + goto exception; + +/* +* ctxt->ops->set_segment expects the CPL to be in +* SS.DPL, so fake an expand-up 32-bit data segment. +*/ + seg_desc.type =3 ; + seg_desc.p =1 ; + seg_desc.s =1 ; + seg_desc.dpl = cpl; + seg_desc.d =1 ; + seg_desc.g =1 ; + } + +/* Skip all following checks */ goto load; + } ret =read_segment_descriptor (ctxt, selector, &seg_desc, &desc_addr);if (ret !=X86EMUL_CONTINUE )
@@ -1698,6 +1711,21 @@ static int load_segment_descriptor(struc u16 selector, int seg) {u8 cpl = ctxt->ops->cpl (ctxt); + +/* +* None of MOV, POP and LSS can load a NULL selector in CPL=3, but +* they can load it at CPL<3 (Intel's manual says only LSS can, +* but it's wrong). +* +* However, the Intel manual says that putting IST=1/DPL=3 in +* an interrupt gate will result in SS=3 (the AMD manual instead +* says it doesn't), so allow SS=3 in __load_segment_descriptor +* and only forbid it here. +*/ +if (seg ==VCPU_SREG_SS && selector ==3 && + ctxt->mode ==X86EMUL_MODE_PROT64 ) +return emulate_exception (ctxt,GP_VECTOR ,0 , true); +return __load_segment_descriptor (ctxt, selector, seg, cpl,X86_TRANSFER_NONE ,NULL ); }
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/kvm-eventfd-fix-null-deref-irqbypass-consumer.patch queue-4.4/kvm-x86-introduce-segmented_write_std.patch queue-4.4/kvm-x86-flush-pending-lapic-jump-label-updates-on-module-unload.patch queue-4.4/kvm-x86-fix-emulation-of-mov-ss-null-selector.patch