[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen stable-4.16] x86/p2m: refuse new allocations for dying domains



commit 745e0b300dc3f5000e6d48c273b405d4bcc29ba7
Author:     Roger Pau Monné <roger.pau@xxxxxxxxxx>
AuthorDate: Tue Oct 11 14:53:41 2022 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Tue Oct 11 14:53:41 2022 +0200

    x86/p2m: refuse new allocations for dying domains
    
    This will in particular prevent any attempts to add entries to the p2m,
    once - in a subsequent change - non-root entries have been removed.
    
    This is part of CVE-2022-33746 / XSA-410.
    
    Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Acked-by: Tim Deegan <tim@xxxxxxx>
    master commit: ff600a8cf8e36f8ecbffecf96a035952e022ab87
    master date: 2022-10-11 14:23:22 +0200
---
 xen/arch/x86/mm/hap/hap.c       |  5 ++++-
 xen/arch/x86/mm/shadow/common.c | 18 ++++++++++++++----
 2 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/xen/arch/x86/mm/hap/hap.c b/xen/arch/x86/mm/hap/hap.c
index d75dc2b9ed..787991233e 100644
--- a/xen/arch/x86/mm/hap/hap.c
+++ b/xen/arch/x86/mm/hap/hap.c
@@ -245,6 +245,9 @@ static struct page_info *hap_alloc(struct domain *d)
 
     ASSERT(paging_locked_by_me(d));
 
+    if ( unlikely(d->is_dying) )
+        return NULL;
+
     pg = page_list_remove_head(&d->arch.paging.hap.freelist);
     if ( unlikely(!pg) )
         return NULL;
@@ -281,7 +284,7 @@ static struct page_info *hap_alloc_p2m_page(struct domain 
*d)
         d->arch.paging.hap.p2m_pages++;
         ASSERT(!page_get_owner(pg) && !(pg->count_info & PGC_count_mask));
     }
-    else if ( !d->arch.paging.p2m_alloc_failed )
+    else if ( !d->arch.paging.p2m_alloc_failed && !d->is_dying )
     {
         d->arch.paging.p2m_alloc_failed = 1;
         dprintk(XENLOG_ERR, "d%i failed to allocate from HAP pool\n",
diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c
index 2067c7d16b..9807f6ec6c 100644
--- a/xen/arch/x86/mm/shadow/common.c
+++ b/xen/arch/x86/mm/shadow/common.c
@@ -939,6 +939,10 @@ static bool __must_check _shadow_prealloc(struct domain 
*d, unsigned int pages)
     if ( d->arch.paging.shadow.free_pages >= pages )
         return true;
 
+    if ( unlikely(d->is_dying) )
+        /* No reclaim when the domain is dying, teardown will take care of it. 
*/
+        return false;
+
     /* Shouldn't have enabled shadows if we've no vcpus. */
     ASSERT(d->vcpu && d->vcpu[0]);
 
@@ -991,7 +995,7 @@ static bool __must_check _shadow_prealloc(struct domain *d, 
unsigned int pages)
            d->arch.paging.shadow.free_pages,
            d->arch.paging.shadow.p2m_pages);
 
-    ASSERT(d->is_dying);
+    ASSERT_UNREACHABLE();
 
     guest_flush_tlb_mask(d, d->dirty_cpumask);
 
@@ -1005,10 +1009,13 @@ static bool __must_check _shadow_prealloc(struct domain 
*d, unsigned int pages)
  * to avoid freeing shadows that the caller is currently working on. */
 bool shadow_prealloc(struct domain *d, unsigned int type, unsigned int count)
 {
-    bool ret = _shadow_prealloc(d, shadow_size(type) * count);
+    bool ret;
 
-    if ( !ret && !d->is_dying &&
-         (!d->is_shutting_down || d->shutdown_code != SHUTDOWN_crash) )
+    if ( unlikely(d->is_dying) )
+       return false;
+
+    ret = _shadow_prealloc(d, shadow_size(type) * count);
+    if ( !ret && (!d->is_shutting_down || d->shutdown_code != SHUTDOWN_crash) )
         /*
          * Failing to allocate memory required for shadow usage can only 
result in
          * a domain crash, do it here rather that relying on every caller to 
do it.
@@ -1238,6 +1245,9 @@ shadow_alloc_p2m_page(struct domain *d)
 {
     struct page_info *pg = NULL;
 
+    if ( unlikely(d->is_dying) )
+       return NULL;
+
     /* This is called both from the p2m code (which never holds the
      * paging lock) and the log-dirty code (which always does). */
     paging_lock_recursive(d);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.16



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.