[xen stable-4.5] x86/shadow: fix ref-counting error handling

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[xen stable-4.5] x86/shadow: fix ref-counting error handling

patchbot
commit 7e02b65a8509bd98adec5ff48fe763ea5fc98abc
Author:     Jan Beulich <[hidden email]>
AuthorDate: Tue Dec 12 15:13:09 2017 +0100
Commit:     Jan Beulich <[hidden email]>
CommitDate: Tue Dec 12 15:13:09 2017 +0100

    x86/shadow: fix ref-counting error handling
   
    The old-Linux handling in shadow_set_l4e() mistakenly ORed together the
    results of sh_get_ref() and sh_pin(). As the latter failing is not a
    correctness problem, simply ignore its return value.
   
    In sh_set_toplevel_shadow() a failing sh_get_ref() must not be
    accompanied by installing the entry, despite the domain being crashed.
   
    This is XSA-250.
   
    Signed-off-by: Jan Beulich <[hidden email]>
    Reviewed-by: Tim Deegan <[hidden email]>
    master commit: 10be8001de7d87be1f0ccdda75cc70e922e56d03
    master date: 2017-12-12 14:29:45 +0100
---
 xen/arch/x86/mm/shadow/multi.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c
index f1cb5f3..c159d15 100644
--- a/xen/arch/x86/mm/shadow/multi.c
+++ b/xen/arch/x86/mm/shadow/multi.c
@@ -896,7 +896,7 @@ static int shadow_set_l4e(struct vcpu *v,
                           shadow_l4e_t new_sl4e,
                           mfn_t sl4mfn)
 {
-    int flags = 0, ok;
+    int flags = 0;
     shadow_l4e_t old_sl4e;
     paddr_t paddr;
     ASSERT(sl4e != NULL);
@@ -911,15 +911,16 @@ static int shadow_set_l4e(struct vcpu *v,
     {
         /* About to install a new reference */        
         mfn_t sl3mfn = shadow_l4e_get_mfn(new_sl4e);
-        ok = sh_get_ref(v, sl3mfn, paddr);
-        /* Are we pinning l3 shadows to handle wierd linux behaviour? */
-        if ( sh_type_is_pinnable(v, SH_type_l3_64_shadow) )
-            ok |= sh_pin(v, sl3mfn);
-        if ( !ok )
+
+        if ( !sh_get_ref(v, sl3mfn, paddr) )
         {
             domain_crash(v->domain);
             return SHADOW_SET_ERROR;
         }
+
+        /* Are we pinning l3 shadows to handle weird Linux behaviour? */
+        if ( sh_type_is_pinnable(v, SH_type_l3_64_shadow) )
+            sh_pin(v, sl3mfn);
     }
 
     /* Write the new entry */
@@ -3881,14 +3882,15 @@ sh_set_toplevel_shadow(struct vcpu *v,
 
     /* Take a ref to this page: it will be released in sh_detach_old_tables()
      * or the next call to set_toplevel_shadow() */
-    if ( !sh_get_ref(v, smfn, 0) )
+    if ( sh_get_ref(v, smfn, 0) )
+        new_entry = pagetable_from_mfn(smfn);
+    else
     {
         SHADOW_ERROR("can't install %#lx as toplevel shadow\n", mfn_x(smfn));
         domain_crash(v->domain);
+        new_entry = pagetable_null();
     }
 
-    new_entry = pagetable_from_mfn(smfn);
-
  install_new_entry:
     /* Done.  Install it */
     SHADOW_PRINTK("%u/%u [%u] gmfn %#"PRI_mfn" smfn %#"PRI_mfn"\n",
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.5

_______________________________________________
Xen-changelog mailing list
[hidden email]
https://lists.xenproject.org/xen-changelog