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)
committerPaolo Bonzini <pbonzini@redhat.com>
Mon, 27 Jan 2020 18:59:42 +0000 (19:59 +0100)
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>
arch/x86/kvm/emulate.c

index 2d4faef..20c0cbd 100644 (file)
@@ -5195,16 +5195,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)