xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* Xen Security Advisory 212 (CVE-2017-7228) - x86: broken check in memory_exchange() permits PV guest breakout
@ 2017-04-04 12:37 Xen.org security team
  0 siblings, 0 replies; only message in thread
From: Xen.org security team @ 2017-04-04 12:37 UTC (permalink / raw)
  To: xen-announce, xen-devel, xen-users, oss-security; +Cc: Xen.org security team

[-- Attachment #1: Type: text/plain, Size: 3151 bytes --]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

            Xen Security Advisory CVE-2017-7228 / XSA-212
                              version 3

       x86: broken check in memory_exchange() permits PV guest breakout

UPDATES IN VERSION 3
====================

Public release.

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

The XSA-29 fix introduced an insufficient check on XENMEM_exchange
input, allowing the caller to drive hypervisor memory accesses outside
of the guest provided input/output arrays.

IMPACT
======

A malicious or buggy 64-bit PV guest may be able to access all of
system memory, allowing for all of privilege escalation, host crashes,
and information leaks.

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

All Xen versions are vulnerable.

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

The vulnerability is only exposed to 64-bit PV guests.  HVM guests and
32-bit PV guests can't exploit the vulnerability.

MITIGATION
==========

Running only HVM or 32-bit PV guests will avoid the vulnerability.

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 Jann Horn of Google Project Zero.

RESOLUTION
==========

Applying the attached patch resolves this issue.

xsa212.patch           xen-unstable, Xen 4.8.x, Xen 4.7.x, Xen 4.6.x, Xen 4.5.x, Xen 4.4.x

$ sha256sum xsa212*
be1255bcda06158cdb86eb5297e8a271e05318e88cd21035c58a67f9ada6ccba  xsa212.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

iQEcBAEBAgAGBQJY45NxAAoJEIP+FMlX6CvZMRMH/jGfTS4hcPuPAiarYhD4D4YQ
pVir0eM/gm/8yJE/CT3m3dieKjjl+GAFW4ehRMoIoxVdSlhiwskx5V+8I5qR/Lo6
6F9BPJw6eaEM62yw7YvMl7EuSexP3WgQeyRSf3BckZ0oxEPSHrIUi0/p0B7FNOFr
C1EqK9d08dMKA5AEugpXgDI0t7fbYg3Kkm8SVnW5B8+5OI/iyTOOkFoPx1sbEvWX
k+zgzodsDuoh8O25+pKVs+verknzGJm9UdCD7vHW8elLg1+1nS2BlfTSr478cDTE
FnbnpuE7r1X/HHd2hPHDAZu3g2IUqfBJCLeYZfhIM9Eioei6bVLXh0f33DvlH/U=
=L74k
-----END PGP SIGNATURE-----

[-- Attachment #2: xsa212.patch --]
[-- Type: application/octet-stream, Size: 3392 bytes --]

memory: properly check guest memory ranges in XENMEM_exchange handling

The use of guest_handle_okay() here (as introduced by the XSA-29 fix)
is insufficient here, guest_handle_subrange_okay() needs to be used
instead.

Note that the uses are okay in
- XENMEM_add_to_physmap_batch handling due to the size field being only
  16 bits wide,
- livepatch_list() due to the limit of 1024 enforced on the
  number-of-entries input (leaving aside the fact that this can be
  called by a privileged domain only anyway),
- compat mode handling due to counts there being limited to 32 bits,
- everywhere else due to guest arrays being accessed sequentially from
  index zero.

This is XSA-212.

Reported-by: Jann Horn <jannh@google.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>

--- a/xen/common/memory.c
+++ b/xen/common/memory.c
@@ -436,8 +436,8 @@ static long memory_exchange(XEN_GUEST_HA
         goto fail_early;
     }
 
-    if ( !guest_handle_okay(exch.in.extent_start, exch.in.nr_extents) ||
-         !guest_handle_okay(exch.out.extent_start, exch.out.nr_extents) )
+    if ( !guest_handle_subrange_okay(exch.in.extent_start, exch.nr_exchanged,
+                                     exch.in.nr_extents - 1) )
     {
         rc = -EFAULT;
         goto fail_early;
@@ -447,11 +447,27 @@ static long memory_exchange(XEN_GUEST_HA
     {
         in_chunk_order  = exch.out.extent_order - exch.in.extent_order;
         out_chunk_order = 0;
+
+        if ( !guest_handle_subrange_okay(exch.out.extent_start,
+                                         exch.nr_exchanged >> in_chunk_order,
+                                         exch.out.nr_extents - 1) )
+        {
+            rc = -EFAULT;
+            goto fail_early;
+        }
     }
     else
     {
         in_chunk_order  = 0;
         out_chunk_order = exch.in.extent_order - exch.out.extent_order;
+
+        if ( !guest_handle_subrange_okay(exch.out.extent_start,
+                                         exch.nr_exchanged << out_chunk_order,
+                                         exch.out.nr_extents - 1) )
+        {
+            rc = -EFAULT;
+            goto fail_early;
+        }
     }
 
     d = rcu_lock_domain_by_any_id(exch.in.domid);
--- a/xen/include/asm-x86/x86_64/uaccess.h
+++ b/xen/include/asm-x86/x86_64/uaccess.h
@@ -29,8 +29,9 @@ extern void *xlat_malloc(unsigned long *
 /*
  * Valid if in +ve half of 48-bit address space, or above Xen-reserved area.
  * This is also valid for range checks (addr, addr+size). As long as the
- * start address is outside the Xen-reserved area then we will access a
- * non-canonical address (and thus fault) before ever reaching VIRT_START.
+ * start address is outside the Xen-reserved area, sequential accesses
+ * (starting at addr) will hit a non-canonical address (and thus fault)
+ * before ever reaching VIRT_START.
  */
 #define __addr_ok(addr) \
     (((unsigned long)(addr) < (1UL<<47)) || \
@@ -40,7 +41,8 @@ extern void *xlat_malloc(unsigned long *
     (__addr_ok(addr) || is_compat_arg_xlat_range(addr, size))
 
 #define array_access_ok(addr, count, size) \
-    (access_ok(addr, (count)*(size)))
+    (likely(((count) ?: 0UL) < (~0UL / (size))) && \
+     access_ok(addr, (count) * (size)))
 
 #define __compat_addr_ok(d, addr) \
     ((unsigned long)(addr) < HYPERVISOR_COMPAT_VIRT_START(d))

[-- Attachment #3: Type: text/plain, Size: 127 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2017-04-04 12:37 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-04-04 12:37 Xen Security Advisory 212 (CVE-2017-7228) - x86: broken check in memory_exchange() permits PV guest breakout Xen.org security team

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).