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 <nmanthey@amazon.de>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
Norbert Manthey authored and Jan Beulich committed 2019-05-24 10:28:26 +02:00
1 parent 2f44d1b3a2
commit 7e69db644a
1 file changed
+29 -4
+29 -4
View File
@@ -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;
}
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.