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

[Xen-devel] [PATCH 2/4] 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 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.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>

--- 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
     {
         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,
     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 )





_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

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