diff options
Diffstat (limited to '5f046c78-EPT-atomically-modify-ents-in-ept_next_level.patch')
| -rw-r--r-- | 5f046c78-EPT-atomically-modify-ents-in-ept_next_level.patch | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/5f046c78-EPT-atomically-modify-ents-in-ept_next_level.patch b/5f046c78-EPT-atomically-modify-ents-in-ept_next_level.patch new file mode 100644 index 0000000..29c102f --- /dev/null +++ b/5f046c78-EPT-atomically-modify-ents-in-ept_next_level.patch @@ -0,0 +1,53 @@ +# Commit bc3d9f95d661372b059a5539ae6cb1e79435bb95 +# Date 2020-07-07 14:37:12 +0200 +# Author Roger Pau Monné <roger.pau@citrix.com> +# Committer Jan Beulich <jbeulich@suse.com> +x86/ept: atomically modify entries in ept_next_level + +ept_next_level was passing a live PTE pointer to ept_set_middle_entry, +which was then modified without taking into account that the PTE could +be part of a live EPT table. This wasn't a security issue because the +pages returned by p2m_alloc_ptp are zeroed, so adding such an entry +before actually initializing it didn't allow a guest to access +physical memory addresses it wasn't supposed to access. + +This is part of XSA-328. + +Reported-by: Jan Beulich <jbeulich@suse.com> +Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> + +--- a/xen/arch/x86/mm/p2m-ept.c ++++ b/xen/arch/x86/mm/p2m-ept.c +@@ -307,6 +307,8 @@ static int ept_next_level(struct p2m_dom + ept_entry_t *ept_entry, *next = NULL, e; + u32 shift, index; + ++ ASSERT(next_level); ++ + shift = next_level * EPT_TABLE_ORDER; + + index = *gfn_remainder >> shift; +@@ -323,16 +325,20 @@ static int ept_next_level(struct p2m_dom + + if ( !is_epte_present(&e) ) + { ++ int rc; ++ + if ( e.sa_p2mt == p2m_populate_on_demand ) + return GUEST_TABLE_POD_PAGE; + + if ( read_only ) + return GUEST_TABLE_MAP_FAILED; + +- next = ept_set_middle_entry(p2m, ept_entry); ++ next = ept_set_middle_entry(p2m, &e); + if ( !next ) + return GUEST_TABLE_MAP_FAILED; +- /* e is now stale and hence may not be used anymore below. */ ++ ++ rc = atomic_write_ept_entry(p2m, ept_entry, e, next_level); ++ ASSERT(rc == 0); + } + /* The only time sp would be set here is if we had hit a superpage */ + else if ( is_epte_superpage(&e) ) |
