[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen master] x86/vMSI: avoid speculative out of bounds accesses



commit be15c231e7e351ea8dbcabf62f952537c637343d
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Thu Jul 4 16:06:27 2019 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Thu Jul 4 16:06:27 2019 +0200

    x86/vMSI: avoid speculative out of bounds accesses
    
    Array indexes used in the MMIO read/write emulation functions are
    derived from guest controlled values. Restrict their ranges to limit the
    side effects of speculative execution.
    
    Note that the index into .msi_ad[] may also be speculatively out of
    bounds, by exactly one (indexes 0...3 are possible while the array has
    just 3 elements). This is not a problem with the current data layout, as
    such overrun of the array would either touch the next element of the
    parent array or (for the last entry of the parent array) access the
    subsequent acc_valid bit array.
    
    This is part of the speculative hardening effort.
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
 xen/arch/x86/hvm/vmsi.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/xen/arch/x86/hvm/vmsi.c b/xen/arch/x86/hvm/vmsi.c
index aeb5a70104..6597d9f719 100644
--- a/xen/arch/x86/hvm/vmsi.c
+++ b/xen/arch/x86/hvm/vmsi.c
@@ -29,6 +29,7 @@
 #include <xen/xmalloc.h>
 #include <xen/lib.h>
 #include <xen/errno.h>
+#include <xen/nospec.h>
 #include <xen/sched.h>
 #include <xen/softirq.h>
 #include <xen/irq.h>
@@ -231,8 +232,10 @@ static int msixtbl_read(const struct hvm_io_handler 
*handler,
     {
         nr_entry = (address - entry->gtable) / PCI_MSIX_ENTRY_SIZE;
         index = offset / sizeof(uint32_t);
-        if ( nr_entry >= MAX_MSIX_ACC_ENTRIES ||
-             !acc_bit(test, entry, nr_entry, index) )
+        if ( nr_entry >= ARRAY_SIZE(entry->gentries) )
+            goto out;
+        nr_entry = array_index_nospec(nr_entry, ARRAY_SIZE(entry->gentries));
+        if ( !acc_bit(test, entry, nr_entry, index) )
             goto out;
         *pval = entry->gentries[nr_entry].msi_ad[index];
         if ( len == 8 )
@@ -284,14 +287,18 @@ static int msixtbl_write(struct vcpu *v, unsigned long 
address,
     entry = msixtbl_find_entry(v, address);
     if ( !entry )
         goto out;
-    nr_entry = (address - entry->gtable) / PCI_MSIX_ENTRY_SIZE;
+    nr_entry = array_index_nospec(((address - entry->gtable) /
+                                   PCI_MSIX_ENTRY_SIZE),
+                                  MAX_MSIX_TABLE_ENTRIES);
 
     offset = address & (PCI_MSIX_ENTRY_SIZE - 1);
     if ( offset != PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET )
     {
         index = offset / sizeof(uint32_t);
-        if ( nr_entry < MAX_MSIX_ACC_ENTRIES ) 
+        if ( nr_entry < ARRAY_SIZE(entry->gentries) )
         {
+            nr_entry = array_index_nospec(nr_entry,
+                                          ARRAY_SIZE(entry->gentries));
             entry->gentries[nr_entry].msi_ad[index] = val;
             acc_bit(set, entry, nr_entry, index);
             if ( len == 8 && !index )
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.