diff options
Diffstat (limited to 'main/xen/xsa378-4.13-8.patch')
-rw-r--r-- | main/xen/xsa378-4.13-8.patch | 157 |
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, |