aboutsummaryrefslogtreecommitdiffstats
path: root/main/xen/xsa378-4.13-8.patch
diff options
context:
space:
mode:
Diffstat (limited to 'main/xen/xsa378-4.13-8.patch')
-rw-r--r--main/xen/xsa378-4.13-8.patch157
1 files changed, 0 insertions, 157 deletions
diff --git a/main/xen/xsa378-4.13-8.patch b/main/xen/xsa378-4.13-8.patch
deleted file mode 100644
index d91dbc3b65c..00000000000
--- a/main/xen/xsa378-4.13-8.patch
+++ /dev/null
@@ -1,157 +0,0 @@
-From: Jan Beulich <jbeulich@suse.com>
-Subject: x86/p2m: guard (in particular) identity mapping entries
-
-Such entries, created by set_identity_p2m_entry(), should only be
-destroyed by clear_identity_p2m_entry(). However, similarly, entries
-created by set_mmio_p2m_entry() should only be torn down by
-clear_mmio_p2m_entry(), so the logic gets based upon p2m_mmio_direct as
-the entry type (separation between "ordinary" and 1:1 mappings would
-require a further indicator to tell apart the two).
-
-As to the guest_remove_page() change, commit 48dfb297a20a ("x86/PVH:
-allow guest_remove_page to remove p2m_mmio_direct pages"), which
-introduced the call to clear_mmio_p2m_entry(), claimed this was done for
-hwdom only without this actually having been the case. However, this
-code shouldn't be there in the first place, as MMIO entries shouldn't be
-dropped this way. Avoid triggering the warning again that 48dfb297a20a
-silenced by an adjustment to xenmem_add_to_physmap_one() instead.
-
-Note that guest_physmap_mark_populate_on_demand() gets tightened beyond
-the immediate purpose of this change.
-
-Note also that I didn't inspect code which isn't security supported,
-e.g. sharing, paging, or altp2m.
-
-This is CVE-2021-28694 / part of XSA-378.
-
-Signed-off-by: Jan Beulich <jbeulich@suse.com>
-Reviewed-by: Paul Durrant <paul@xen.org>
-
---- a/xen/arch/x86/mm.c
-+++ b/xen/arch/x86/mm.c
-@@ -4770,7 +4770,9 @@ int xenmem_add_to_physmap_one(
-
- /* Remove previously mapped page if it was present. */
- prev_mfn = get_gfn(d, gfn_x(gpfn), &p2mt);
-- if ( mfn_valid(prev_mfn) )
-+ if ( p2mt == p2m_mmio_direct )
-+ rc = -EPERM;
-+ else if ( mfn_valid(prev_mfn) )
- {
- if ( is_xen_heap_mfn(prev_mfn) )
- /* Xen heap frames are simply unhooked from this phys slot. */
---- a/xen/arch/x86/mm/p2m.c
-+++ b/xen/arch/x86/mm/p2m.c
-@@ -796,7 +796,8 @@ p2m_remove_page(struct p2m_domain *p2m,
- &cur_order, NULL);
-
- if ( p2m_is_valid(t) &&
-- (!mfn_valid(_mfn(mfn)) || mfn + i != mfn_x(mfn_return)) )
-+ (!mfn_valid(_mfn(mfn)) || t == p2m_mmio_direct ||
-+ mfn + i != mfn_x(mfn_return)) )
- return -EILSEQ;
-
- i += (1UL << cur_order) - ((gfn_l + i) & ((1UL << cur_order) - 1));
-@@ -890,7 +891,7 @@ guest_physmap_add_entry(struct domain *d
- if ( p2m_is_foreign(t) )
- return -EINVAL;
-
-- if ( !mfn_valid(mfn) )
-+ if ( !mfn_valid(mfn) || t == p2m_mmio_direct )
- {
- ASSERT_UNREACHABLE();
- return -EINVAL;
-@@ -936,7 +937,7 @@ guest_physmap_add_entry(struct domain *d
- }
- if ( p2m_is_special(ot) )
- {
-- /* Don't permit unmapping grant/foreign this way. */
-+ /* Don't permit unmapping grant/foreign/direct-MMIO this way. */
- domain_crash(d);
- p2m_unlock(p2m);
-
-@@ -1385,8 +1386,8 @@ int set_identity_p2m_entry(struct domain
- * order+1 for caller to retry with order (guaranteed smaller than
- * the order value passed in)
- */
--int clear_mmio_p2m_entry(struct domain *d, unsigned long gfn_l, mfn_t mfn,
-- unsigned int order)
-+static int clear_mmio_p2m_entry(struct domain *d, unsigned long gfn_l,
-+ mfn_t mfn, unsigned int order)
- {
- int rc = -EINVAL;
- gfn_t gfn = _gfn(gfn_l);
---- a/xen/arch/x86/mm/p2m-pod.c
-+++ b/xen/arch/x86/mm/p2m-pod.c
-@@ -1295,17 +1295,17 @@ guest_physmap_mark_populate_on_demand(st
-
- p2m->get_entry(p2m, gfn_add(gfn, i), &ot, &a, 0, &cur_order, NULL);
- n = 1UL << min(order, cur_order);
-- if ( p2m_is_ram(ot) )
-+ if ( ot == p2m_populate_on_demand )
-+ {
-+ /* Count how many PoD entries we'll be replacing if successful */
-+ pod_count += n;
-+ }
-+ else if ( ot != p2m_invalid && ot != p2m_mmio_dm )
- {
- P2M_DEBUG("gfn_to_mfn returned type %d!\n", ot);
- rc = -EBUSY;
- goto out;
- }
-- else if ( ot == p2m_populate_on_demand )
-- {
-- /* Count how man PoD entries we'll be replacing if successful */
-- pod_count += n;
-- }
- }
-
- /* Now, actually do the two-way mapping */
---- a/xen/common/memory.c
-+++ b/xen/common/memory.c
-@@ -328,7 +328,7 @@ int guest_remove_page(struct domain *d,
- }
- if ( p2mt == p2m_mmio_direct )
- {
-- rc = clear_mmio_p2m_entry(d, gmfn, mfn, PAGE_ORDER_4K);
-+ rc = -EPERM;
- goto out_put_gfn;
- }
- #else
-@@ -1720,6 +1720,15 @@ int check_get_page_from_gfn(struct domai
- return -EAGAIN;
- }
- #endif
-+#ifdef CONFIG_X86
-+ if ( p2mt == p2m_mmio_direct )
-+ {
-+ if ( page )
-+ put_page(page);
-+
-+ return -EPERM;
-+ }
-+#endif
-
- if ( !page )
- return -EINVAL;
---- a/xen/include/asm-x86/p2m.h
-+++ b/xen/include/asm-x86/p2m.h
-@@ -143,7 +143,8 @@ typedef unsigned int p2m_query_t;
-
- /* Types established/cleaned up via special accessors. */
- #define P2M_SPECIAL_TYPES (P2M_GRANT_TYPES | \
-- p2m_to_mask(p2m_map_foreign))
-+ p2m_to_mask(p2m_map_foreign) | \
-+ p2m_to_mask(p2m_mmio_direct))
-
- /* Valid types not necessarily associated with a (valid) MFN. */
- #define P2M_INVALID_MFN_TYPES (P2M_POD_TYPES \
-@@ -649,8 +650,6 @@ int set_foreign_p2m_entry(struct domain
- /* Set mmio addresses in the p2m table (for pass-through) */
- int set_mmio_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn,
- unsigned int order, p2m_access_t access);
--int clear_mmio_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn,
-- unsigned int order);
-
- /* Set identity addresses in the p2m table (for pass-through) */
- int set_identity_p2m_entry(struct domain *d, unsigned long gfn,