KVM: x86: Protect MSR-based index computations from Spectre-v1/L1TF attacks in x86.c
authorMarios Pomonis <pomonis@google.com>
Wed, 11 Dec 2019 20:47:49 +0000 (12:47 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 14 Feb 2020 21:31:04 +0000 (16:31 -0500)
commit 6ec4c5eee1750d5d17951c4e1960d953376a0dda upstream.

This fixes a Spectre-v1/L1TF vulnerability in set_msr_mce() and
get_msr_mce().
Both functions contain index computations based on the
(attacker-controlled) MSR number.

Fixes: 890ca9aefa78 ("KVM: Add MCE support")

Signed-off-by: Nick Finco <nifi@google.com>
Signed-off-by: Marios Pomonis <pomonis@google.com>
Reviewed-by: Andrew Honig <ahonig@google.com>
Cc: stable@vger.kernel.org
Reviewed-by: Jim Mattson <jmattson@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/kvm/x86.c

index 9da4528..4e8ab40 100644 (file)
@@ -2130,7 +2130,10 @@ static int set_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 data)
        default:
                if (msr >= MSR_IA32_MC0_CTL &&
                    msr < MSR_IA32_MCx_CTL(bank_num)) {
-                       u32 offset = msr - MSR_IA32_MC0_CTL;
+                       u32 offset = array_index_nospec(
+                               msr - MSR_IA32_MC0_CTL,
+                               MSR_IA32_MCx_CTL(bank_num) - MSR_IA32_MC0_CTL);
+
                        /* only 0 or all 1s can be written to IA32_MCi_CTL
                         * some Linux kernels though clear bit 10 in bank 4 to
                         * workaround a BIOS/GART TBL issue on AMD K8s, ignore
@@ -2498,7 +2501,10 @@ static int get_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
        default:
                if (msr >= MSR_IA32_MC0_CTL &&
                    msr < MSR_IA32_MCx_CTL(bank_num)) {
-                       u32 offset = msr - MSR_IA32_MC0_CTL;
+                       u32 offset = array_index_nospec(
+                               msr - MSR_IA32_MC0_CTL,
+                               MSR_IA32_MCx_CTL(bank_num) - MSR_IA32_MC0_CTL);
+
                        data = vcpu->arch.mce_banks[offset];
                        break;
                }