Xen Security Advisory 242 - page type reference leak on x86

Xen.org security team <[email protected]>
Newsgroups gmane.comp.emulators.xen.announce
Message-ID <E1e2cPg-0007Ct-RO__1742.31414353034$1507810976$gmane$org@xenbits.xenproject.org>
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

                    Xen Security Advisory XSA-242
                              version 2

                    page type reference leak on x86

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

Public release.

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

The page type system of Xen requires cleanup when the last reference
for a given page is being dropped.  In order to exclude simultaneous
updates to a given page by multiple parties, pages which are updated
are locked beforehand.  This locking includes temporarily increasing
the type reference count by one.  When the page is later unlocked, the
context precludes cleanup, so the reference that is then dropped must
not be the last one.  This was not properly enforced.

IMPACT
======

A malicious or buggy PV guest may cause a memory leak upon shutdown
of the guest, ultimately perhaps resulting in Denial of Service (DoS)
affecting the entire host.

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

All Xen versions from 3.4 onwards are vulnerable.  Xen versions 3.3 and
earlier are not vulnerable.

Only x86 systems are affected.  ARM systems are not affected.

Only x86 PV guests can leverage the vulnerability.  x86 HVM guests
cannot leverage the vulnerability.

MITIGATION
==========

Running only HVM guests will avoid this vulnerability.

For PV guests, the vulnerability can be avoided if the guest kernel is
controlled by the host rather than guest administrator, provided that
further steps are taken to prevent the guest administrator from loading
code into the kernel (e.g. by disabling loadable modules etc) or from
using other mechanisms which allow them to run code at kernel privilege.

CREDITS
=======

This issue was discovered by Jan Beulich of SUSE.

RESOLUTION
==========

Applying the appropriate attached patch resolves this issue.

xsa242.patch           xen-unstable
xsa242-4.9.patch       Xen 4.9.x, Xen 4.8.x, Xen 4.7.x, Xen 4.6.x, Xen 4.5.x

$ sha256sum xsa242*
168db3aef00806025afa255dee35cd0c042706a27a0256744e4d63f3ee86a2e8  xsa242.meta
16848f71311c2fd6a38afd7602e59211c89a3daf29b874097dba0b1e31ba6eec  xsa242.patch
5e66b6b1d1cd400905d3abd3478144539c3afa24f5a744a11809d9c5eb517b98  xsa242-4.9.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-----
Version: GnuPG v1

iQEcBAEBCAAGBQJZ31wBAAoJEIP+FMlX6CvZs4YH+QH5lTpge4JLyHQRJbLry52Z
70oB+1vZIsoWg9/XONE9/l1kei0WOGPh4Pt2AWUZOXy8I/euHlMUeGZchl7cQ73M
6EOPjQ1+EXv+vIePwyjZiZmjKQJYQDZ5IsNZ3lz2oV27SkppSW6KKPFlj9G3Dc+E
Fv0JwawHNBruGQu9RYWukLbCKn9g4Z0OD/4OwpzF0PY3c/zqk9aYjg318i2Na5zu
tWDI9+srfzgvT9N2+om/hVBQYHp48OOIUIGtMz7M4A33LBySsETigpBaCiNmyNeG
+l3ONWKF8XNeJbpYGtd3jClgXLg8Hy5MgalSCKOyB2XAgl0y2BSX3tyhOnQZKcs=
=tqOh
-----END PGP SIGNATURE-----

_______________________________________________
Xen-announce mailing list
[email protected]
https://lists.xen.org/xen-announce
xsa242.meta (application/octet-stream, 2.2 KB) - not displayed
xsa242.patch (application/octet-stream, 1.7 KB)
From b2d245c0e7290614798969411614c1902300aafb Mon Sep 17 00:00:00 2001
From: Jan Beulich <[email protected]>
Date: Wed, 27 Sep 2017 11:00:56 +0100
Subject: [PATCH] x86: don't allow page_unlock() to drop the last type
 reference

Only _put_page_type() does the necessary cleanup, and hence not all
domain pages can be released during guest cleanup (leaving around
zombie domains) if we get this wrong.

This is XSA-242.

Signed-off-by: Jan Beulich <[email protected]>
---
 xen/arch/x86/mm.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index ab8f93935c..d883f1d648 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -1705,7 +1705,11 @@ void page_unlock(struct page_info *page)
 
     do {
         x = y;
+        ASSERT((x & PGT_count_mask) && (x & PGT_locked));
+
         nx = x - (1 | PGT_locked);
+        /* We must not drop the last reference here. */
+        ASSERT(nx & PGT_count_mask);
     } while ( (y = cmpxchg(&page->u.inuse.type_info, x, nx)) != x );
 }
 
@@ -2308,6 +2312,17 @@ static int _put_page_type(struct page_info *page, bool preemptible,
 
             set_tlbflush_timestamp(page);
         }
+        else if ( unlikely((nx & (PGT_locked | PGT_count_mask)) ==
+                           (PGT_locked | 1)) )
+        {
+            /*
+             * We must not drop the second to last reference when the page is
+             * locked, as page_unlock() doesn't do any cleanup of the type.
+             */
+            cpu_relax();
+            y = page->u.inuse.type_info;
+            continue;
+        }
 
         if ( likely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) == x) )
             break;
-- 
2.14.1
xsa242-4.9.patch (application/octet-stream, 1.4 KB)
From: Jan Beulich <[email protected]>
Subject: x86: don't allow page_unlock() to drop the last type reference

Only _put_page_type() does the necessary cleanup, and hence not all
domain pages can be released during guest cleanup (leaving around
zombie domains) if we get this wrong.

This is XSA-242.

Signed-off-by: Jan Beulich <[email protected]>

--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -1923,7 +1923,11 @@ void page_unlock(struct page_info *page)
 
     do {
         x = y;
+        ASSERT((x & PGT_count_mask) && (x & PGT_locked));
+
         nx = x - (1 | PGT_locked);
+        /* We must not drop the last reference here. */
+        ASSERT(nx & PGT_count_mask);
     } while ( (y = cmpxchg(&page->u.inuse.type_info, x, nx)) != x );
 }
 
@@ -2611,6 +2615,17 @@ static int _put_page_type(struct page_in
                    (page->count_info & PGC_page_table)) )
                 page_set_tlbflush_timestamp(page);
         }
+        else if ( unlikely((nx & (PGT_locked | PGT_count_mask)) ==
+                           (PGT_locked | 1)) )
+        {
+            /*
+             * We must not drop the second to last reference when the page is
+             * locked, as page_unlock() doesn't do any cleanup of the type.
+             */
+            cpu_relax();
+            y = page->u.inuse.type_info;
+            continue;
+        }
 
         if ( likely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) == x) )
             break;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.