summaryrefslogtreecommitdiff
path: root/5f046c78-EPT-atomically-modify-ents-in-ept_next_level.patch
diff options
context:
space:
mode:
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.patch53
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) )