]> xenbits.xensource.com Git - people/liuw/xen.git/commitdiff
x86/hvm: block speculative out-of-bound accesses
authorNorbert Manthey <nmanthey@amazon.de>
Tue, 12 Feb 2019 14:20:15 +0000 (15:20 +0100)
committerJan Beulich <jbeulich@suse.com>
Tue, 12 Feb 2019 14:20:15 +0000 (15:20 +0100)
There are multiple arrays in the HVM interface that are accessed
with indices that are provided by the guest. To avoid speculative
out-of-bound accesses, we use the array_index_nospec macro.

When blocking speculative out-of-bound accesses, we can classify arrays
into dynamic arrays and static arrays. Where the former are allocated
during run time, the size of the latter is known during compile time.
On static arrays, compiler might be able to block speculative accesses
in the future.

This is part of the speculative hardening effort.

Reported-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
Signed-off-by: Norbert Manthey <nmanthey@amazon.de>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Release-acked-by: Juergen Gross <jgross@suse.com>
xen/arch/x86/hvm/hvm.c

index 21944e930640a41e9600f224bc7fe1bf4a851b8b..410623d437dd76a02c95c08c0fd9388daa5c83a6 100644 (file)
@@ -37,6 +37,7 @@
 #include <xen/monitor.h>
 #include <xen/warning.h>
 #include <xen/vpci.h>
+#include <xen/nospec.h>
 #include <asm/shadow.h>
 #include <asm/hap.h>
 #include <asm/current.h>
@@ -2092,7 +2093,7 @@ int hvm_mov_from_cr(unsigned int cr, unsigned int gpr)
     case 2:
     case 3:
     case 4:
-        val = curr->arch.hvm.guest_cr[cr];
+        val = array_access_nospec(curr->arch.hvm.guest_cr, cr);
         break;
     case 8:
         val = (vlapic_get_reg(vcpu_vlapic(curr), APIC_TASKPRI) & 0xf0) >> 4;
@@ -3438,13 +3439,15 @@ int hvm_msr_read_intercept(unsigned int msr, uint64_t *msr_content)
         if ( !d->arch.cpuid->basic.mtrr )
             goto gp_fault;
         index = msr - MSR_MTRRfix16K_80000;
-        *msr_content = fixed_range_base[index + 1];
+        *msr_content = fixed_range_base[array_index_nospec(index + 1,
+                                   ARRAY_SIZE(v->arch.hvm.mtrr.fixed_ranges))];
         break;
     case MSR_MTRRfix4K_C0000...MSR_MTRRfix4K_F8000:
         if ( !d->arch.cpuid->basic.mtrr )
             goto gp_fault;
         index = msr - MSR_MTRRfix4K_C0000;
-        *msr_content = fixed_range_base[index + 3];
+        *msr_content = fixed_range_base[array_index_nospec(index + 3,
+                                   ARRAY_SIZE(v->arch.hvm.mtrr.fixed_ranges))];
         break;
     case MSR_IA32_MTRR_PHYSBASE(0)...MSR_IA32_MTRR_PHYSMASK(MTRR_VCNT_MAX - 1):
         if ( !d->arch.cpuid->basic.mtrr )
@@ -3453,7 +3456,9 @@ int hvm_msr_read_intercept(unsigned int msr, uint64_t *msr_content)
         if ( (index / 2) >=
              MASK_EXTR(v->arch.hvm.mtrr.mtrr_cap, MTRRcap_VCNT) )
             goto gp_fault;
-        *msr_content = var_range_base[index];
+        *msr_content = var_range_base[array_index_nospec(index,
+                                      2 * MASK_EXTR(v->arch.hvm.mtrr.mtrr_cap,
+                                                    MTRRcap_VCNT))];
         break;
 
     case MSR_IA32_XSS:
@@ -4016,7 +4021,7 @@ static int hvmop_set_evtchn_upcall_vector(
     if ( op.vector < 0x10 )
         return -EINVAL;
 
-    if ( op.vcpu >= d->max_vcpus || (v = d->vcpu[op.vcpu]) == NULL )
+    if ( (v = domain_vcpu(d, op.vcpu)) == NULL )
         return -ENOENT;
 
     printk(XENLOG_G_INFO "%pv: upcall vector %02x\n", v, op.vector);