[prev in list] [next in list] [prev in thread] [next in thread] 

List:       oss-security
Subject:    [oss-security] Xen Security Advisory 250 - improper x86 shadow mode refcount error handling
From:       Xen.org security team <security () xen ! org>
Date:       2017-12-12 12:00:11
Message-ID: E1eOjEJ-0002EY-VH () xenbits ! xenproject ! org
[Download RAW message or body]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

                    Xen Security Advisory XSA-250
                              version 2

           improper x86 shadow mode refcount error handling

UPDATES IN VERSION 2
====================

Public release.

Provide metadata file.

ISSUE DESCRIPTION
=================

Pages being used to run x86 guests in shadow mode are reference counted
to track their uses.  When another reference cannot be acquired, the
corresponding page table entry must not be inserted.  Due to incorrect
error handling, this constraint could be violated.

IMPACT
======

A malicious or buggy guest may cause a hypervisor crash, resulting in
a Denial of Service (DoS) affecting the entire host, or cause hypervisor
memory corruption.  We cannot rule out a guest being able to escalate
its privilege.

VULNERABLE SYSTEMS
==================

All Xen versions are affected.

x86 systems are vulnerable.  ARM systems are not vulnerable.

Only guests run in shadow mode can exploit the vulnerability.

PV guests typically only run in shadow mode during live migration, as
well as for features like VM snapshot.

Note that save / restore does *not* use shadow mode, and so does not
expose this vulnerability.  Some downstreams also  include a "non-live
migration" feature, which also does not use shadow mode (and thus does
not expose this vulnerability).

HVM guests run in shadow mode on hardware without HAP support, or when
HAP is disabled (globally or in the VM configuration file).  Live
migration does not affect an HVM guest's use of shadow mode.

MITIGATION
==========

For HVM guest explicitly configured to use shadow paging (e.g. via the
`hap=0' xl domain configuration file parameter), changing to HAP (e.g.
by setting `hap=1') will avoid exposing the vulnerability to those
guests.  HAP is the default (in upstream Xen), where the hardware
supports it; so this mitigation is only applicable if HAP has been
disabled by configuration.

For PV guests, avoiding their live migration avoids the vulnerability.

CREDITS
=======

This issue was discovered by Jan Beulich of SUSE.

RESOLUTION
==========

Applying the appropriate attached patch resolves this issue.

xsa250.patch           xen-unstable, Xen 4.9.x ... 4.6.x
xsa250-4.5.patch       Xen 4.5.x

$ sha256sum xsa250*
c15c1c3e64cfb7ab2e2c48970214aa8c3881deb7e11c498526554bb74535b601  xsa250.meta
adf4d8242dbddb4ec52fe1effc1f8b233d33d8d6a59c1bb677dcc6e2ed2bf711  xsa250.patch
d123a58308db606185c4e48dcf4a114ac29bb988ffc0eeb04ded213ec474e0f2  xsa250-4.5.patch
$

DEPLOYMENT DURING EMBARGO
=========================

Deployment of the patches and/or mitigations described above (or
others which are substantially similar) is permitted during the
embargo, even on public-facing systems with untrusted guest users and
administrators.

But: Distribution of updated software is prohibited (except to other
members of the predisclosure list).

Predisclosure list members who wish to deploy significantly different
patches and/or mitigations, please contact the Xen Project Security
Team.

(Note: this during-embargo deployment notice is retained in
post-embargo publicly released Xen Project advisories, even though it
is then no longer applicable.  This is to enable the community to have
oversight of the Xen Project Security Team's decisionmaking.)

For more information about permissible uses of embargoed information,
consult the Xen Project community's agreed Security Policy:
  http://www.xenproject.org/security-policy.html
-----BEGIN PGP SIGNATURE-----

iQFABAEBCAAqFiEEI+MiLBRfRHX6gGCng/4UyVfoK9kFAlovuNkMHHBncEB4ZW4u
b3JnAAoJEIP+FMlX6CvZx+4H/2ADwtz7LzqBd7aZ9BnODa3L+KM/hO05tG0t+feh
eunJSfxAY3jRep4NxWUgK8zerAusw3zZi9lRzmhdLMHYtmslJPDWy5ul0N09E6Y5
KH2Ky8zkFb2puzHZs2oMKywW25aRI6Bs7VdFK44KxWPRrLAFTNup6xOCVNWJ4VWw
YhNTu4g/+mUUa+KLRPL/s6sKjIw07/sbh/koHWSwlAksxmlUfdHaFuLbsvspPRe0
vq8Q8zN/n9Att6i8RrjeWLAb36mYXhKYIzkZhmJXNlwQx9dkhuLdlRaJ4zb7uERb
wDYYlT9wib8CB5tsKxX+ozLQ0mr43DAFfsLJpzi7TudYplE=
=+/I2
-----END PGP SIGNATURE-----

["xsa250.meta" (application/octet-stream)]
["xsa250.patch" (application/octet-stream)]

From: Jan Beulich <jbeulich@suse.com>
Subject: 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 <jbeulich@suse.com>
Reviewed-by: Tim Deegan <tim@xen.org>

--- a/xen/arch/x86/mm/shadow/multi.c
+++ b/xen/arch/x86/mm/shadow/multi.c
@@ -923,7 +923,7 @@ static int shadow_set_l4e(struct domain
                           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);
@@ -938,15 +938,16 @@ static int shadow_set_l4e(struct domain
     {
         /* About to install a new reference */
         mfn_t sl3mfn = shadow_l4e_get_mfn(new_sl4e);
-        ok = sh_get_ref(d, sl3mfn, paddr);
-        /* Are we pinning l3 shadows to handle wierd linux behaviour? */
-        if ( sh_type_is_pinnable(d, SH_type_l3_64_shadow) )
-            ok |= sh_pin(d, sl3mfn);
-        if ( !ok )
+
+        if ( !sh_get_ref(d, sl3mfn, paddr) )
         {
             domain_crash(d);
             return SHADOW_SET_ERROR;
         }
+
+        /* Are we pinning l3 shadows to handle weird Linux behaviour? */
+        if ( sh_type_is_pinnable(d, SH_type_l3_64_shadow) )
+            sh_pin(d, sl3mfn);
     }
 
     /* Write the new entry */
@@ -3965,14 +3966,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(d, smfn, 0) )
+    if ( sh_get_ref(d, smfn, 0) )
+        new_entry = pagetable_from_mfn(smfn);
+    else
     {
         SHADOW_ERROR("can't install %#lx as toplevel shadow\n", mfn_x(smfn));
         domain_crash(d);
+        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",

["xsa250-4.5.patch" (application/octet-stream)]

From: Jan Beulich <jbeulich@suse.com>
Subject: 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 <jbeulich@suse.com>
Reviewed-by: Tim Deegan <tim@xen.org>

--- 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",


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic