Guests can issue grant table operations and provide guest controlled data to them. This data is used for memory loads in helper functions and macros. To avoid speculative out-of-bound accesses, we use the array_index_nospec macro where applicable, or the block_speculation macro.
This is part of the speculative hardening effort. Signed-off-by: Norbert Manthey <nmant...@amazon.de> --- Notes: v1: split the gnttab commit of the previous L1TF series into multiple commits xen/common/grant_table.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -37,6 +37,7 @@ #include <xen/paging.h> #include <xen/keyhandler.h> #include <xen/vmap.h> +#include <xen/nospec.h> #include <xsm/xsm.h> #include <asm/flushtlb.h> @@ -203,8 +204,9 @@ static inline unsigned int nr_status_frames(const struct grant_table *gt) } #define MAPTRACK_PER_PAGE (PAGE_SIZE / sizeof(struct grant_mapping)) -#define maptrack_entry(t, e) \ - ((t)->maptrack[(e)/MAPTRACK_PER_PAGE][(e)%MAPTRACK_PER_PAGE]) +#define maptrack_entry(t, e) \ + ((t)->maptrack[array_index_nospec(e, (t)->maptrack_limit) / \ + MAPTRACK_PER_PAGE][(e) % MAPTRACK_PER_PAGE]) static inline unsigned int nr_maptrack_frames(struct grant_table *t) @@ -226,10 +228,23 @@ nr_maptrack_frames(struct grant_table *t) static grant_entry_header_t * shared_entry_header(struct grant_table *t, grant_ref_t ref) { - if ( t->gt_version == 1 ) + switch ( t->gt_version ) + { + case 1: + /* Returned values should be independent of speculative execution */ + block_speculation(); return (grant_entry_header_t*)&shared_entry_v1(t, ref); - else + + case 2: + /* Returned values should be independent of speculative execution */ + block_speculation(); return &shared_entry_v2(t, ref).hdr; + } + + ASSERT_UNREACHABLE(); + block_speculation(); + + return NULL; } /* Active grant entry - used for shadowing GTF_permit_access grants. */ @@ -634,14 +649,24 @@ static unsigned int nr_grant_entries(struct grant_table *gt) case 1: BUILD_BUG_ON(f2e(INITIAL_NR_GRANT_FRAMES, 1) < GNTTAB_NR_RESERVED_ENTRIES); + + /* Make sure we return a value independently of speculative execution */ + block_speculation(); return f2e(nr_grant_frames(gt), 1); + case 2: BUILD_BUG_ON(f2e(INITIAL_NR_GRANT_FRAMES, 2) < GNTTAB_NR_RESERVED_ENTRIES); + + /* Make sure we return a value independently of speculative execution */ + block_speculation(); return f2e(nr_grant_frames(gt), 2); #undef f2e } + ASSERT_UNREACHABLE(); + block_speculation(); + return 0; } -- 2.7.4 Amazon Development Center Germany GmbH Krausenstr. 38 10117 Berlin Geschaeftsfuehrer: Christian Schlaeger, Ralf Herbrich Ust-ID: DE 289 237 879 Eingetragen am Amtsgericht Charlottenburg HRB 149173 B _______________________________________________ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel