KVM: x86: Refactor prefix decoding to prevent Spectre-v1/L1TF attacks
authorMarios Pomonis <pomonis@google.com>
Wed, 11 Dec 2019 20:47:50 +0000 (12:47 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 14 Feb 2020 21:31:03 +0000 (16:31 -0500)
commit 125ffc5e0a56a3eded608dc51e09d5ebf72cf652 upstream.

This fixes Spectre-v1/L1TF vulnerabilities in
vmx_read_guest_seg_selector(), vmx_read_guest_seg_base(),
vmx_read_guest_seg_limit() and vmx_read_guest_seg_ar().  When
invoked from emulation, these functions contain index computations
based on the (attacker-influenced) segment value.  Using constants
prevents the attack.

Cc: stable@vger.kernel.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/kvm/emulate.c

index 660c35f854f8b6d11d2735512a5b0e8f9591de06..ff20ef3fd8992dbf54397221d6616eb78bc43d76 100644 (file)
@@ -5053,16 +5053,28 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
                                ctxt->ad_bytes = def_ad_bytes ^ 6;
                        break;
                case 0x26:      /* ES override */
+                       has_seg_override = true;
+                       ctxt->seg_override = VCPU_SREG_ES;
+                       break;
                case 0x2e:      /* CS override */
+                       has_seg_override = true;
+                       ctxt->seg_override = VCPU_SREG_CS;
+                       break;
                case 0x36:      /* SS override */
+                       has_seg_override = true;
+                       ctxt->seg_override = VCPU_SREG_SS;
+                       break;
                case 0x3e:      /* DS override */
                        has_seg_override = true;
-                       ctxt->seg_override = (ctxt->b >> 3) & 3;
+                       ctxt->seg_override = VCPU_SREG_DS;
                        break;
                case 0x64:      /* FS override */
+                       has_seg_override = true;
+                       ctxt->seg_override = VCPU_SREG_FS;
+                       break;
                case 0x65:      /* GS override */
                        has_seg_override = true;
-                       ctxt->seg_override = ctxt->b & 7;
+                       ctxt->seg_override = VCPU_SREG_GS;
                        break;
                case 0x40 ... 0x4f: /* REX */
                        if (mode != X86EMUL_MODE_PROT64)