[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen staging] x86/vioapic: block speculative out-of-bound accesses
commit 346e7d0f4b2179b9e0b09f4ebc98cbb3aae39a2c Author: Norbert Manthey <nmanthey@xxxxxxxxx> AuthorDate: Tue Feb 26 16:57:56 2019 +0100 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Tue Feb 26 16:57:56 2019 +0100 x86/vioapic: block speculative out-of-bound accesses When interacting with io apic, a guest can specify values that are used as index to structures, and whose values are not compared against upper bounds to prevent speculative out-of-bound accesses. This change prevents these speculative accesses. Furthermore, variables are initialized and the compiler is asked to not optimized these initializations, as the uninitialized variables might be used in a speculative out-of-bound access. Out of the four initialized variables, two are potentially problematic, namely ones in the functions vioapic_irq_positive_edge and vioapic_get_trigger_mode. As the two problematic variables are both used in the common function gsi_vioapic, the mitigation is implemented there. As the access pattern of the currently non-guest-controlled functions might change in the future as well, the other variables are initialized as well. This is part of the speculative hardening effort. Signed-off-by: Norbert Manthey <nmanthey@xxxxxxxxx> Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx> Release-acked-by: Juergen Gross <jgross@xxxxxxxx> --- xen/arch/x86/hvm/vioapic.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c index 2d71c33c1c..9c25f72b4d 100644 --- a/xen/arch/x86/hvm/vioapic.c +++ b/xen/arch/x86/hvm/vioapic.c @@ -30,6 +30,7 @@ #include <xen/lib.h> #include <xen/errno.h> #include <xen/sched.h> +#include <xen/nospec.h> #include <public/hvm/ioreq.h> #include <asm/hvm/io.h> #include <asm/hvm/vpic.h> @@ -66,6 +67,12 @@ static struct hvm_vioapic *gsi_vioapic(const struct domain *d, { unsigned int i; + /* + * Make sure the compiler does not optimize away the initialization done by + * callers + */ + OPTIMIZER_HIDE_VAR(*pin); + for ( i = 0; i < d->arch.hvm.nr_vioapics; i++ ) { struct hvm_vioapic *vioapic = domain_vioapic(d, i); @@ -117,7 +124,8 @@ static uint32_t vioapic_read_indirect(const struct hvm_vioapic *vioapic) break; } - redir_content = vioapic->redirtbl[redir_index].bits; + redir_content = vioapic->redirtbl[array_index_nospec(redir_index, + vioapic->nr_pins)].bits; result = (vioapic->ioregsel & 1) ? (redir_content >> 32) : redir_content; break; @@ -212,7 +220,15 @@ static void vioapic_write_redirent( struct hvm_irq *hvm_irq = hvm_domain_irq(d); union vioapic_redir_entry *pent, ent; int unmasked = 0; - unsigned int gsi = vioapic->base_gsi + idx; + unsigned int gsi; + + /* Callers of this function should make sure idx is bounded appropriately */ + ASSERT(idx < vioapic->nr_pins); + + /* Make sure no out-of-bounds value for idx can be used */ + idx = array_index_nospec(idx, vioapic->nr_pins); + + gsi = vioapic->base_gsi + idx; spin_lock(&d->arch.hvm.irq_lock); @@ -467,7 +483,7 @@ static void vioapic_deliver(struct hvm_vioapic *vioapic, unsigned int pin) void vioapic_irq_positive_edge(struct domain *d, unsigned int irq) { - unsigned int pin; + unsigned int pin = 0; /* See gsi_vioapic */ struct hvm_vioapic *vioapic = gsi_vioapic(d, irq, &pin); union vioapic_redir_entry *ent; @@ -542,7 +558,7 @@ void vioapic_update_EOI(struct domain *d, u8 vector) int vioapic_get_mask(const struct domain *d, unsigned int gsi) { - unsigned int pin; + unsigned int pin = 0; /* See gsi_vioapic */ const struct hvm_vioapic *vioapic = gsi_vioapic(d, gsi, &pin); if ( !vioapic ) @@ -553,7 +569,7 @@ int vioapic_get_mask(const struct domain *d, unsigned int gsi) int vioapic_get_vector(const struct domain *d, unsigned int gsi) { - unsigned int pin; + unsigned int pin = 0; /* See gsi_vioapic */ const struct hvm_vioapic *vioapic = gsi_vioapic(d, gsi, &pin); if ( !vioapic ) @@ -564,7 +580,7 @@ int vioapic_get_vector(const struct domain *d, unsigned int gsi) int vioapic_get_trigger_mode(const struct domain *d, unsigned int gsi) { - unsigned int pin; + unsigned int pin = 0; /* See gsi_vioapic */ const struct hvm_vioapic *vioapic = gsi_vioapic(d, gsi, &pin); if ( !vioapic ) -- generated by git-patchbot for /home/xen/git/xen.git#staging _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |