From: Norbert Manthey Date: Fri, 24 May 2019 08:28:26 +0000 (+0200) Subject: common/grant_table: harden helpers X-Git-Tag: archive/raspbian/4.14.0+80-gd101b417b7-1+rpi1^2~63^2~2164 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=7e69db644a8138ea28953df88060b6826ec425de;p=xen.git common/grant_table: harden helpers 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 Reviewed-by: Jan Beulich --- diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index 80728ea57d..dd8a9d9046 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -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; }