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

List:       xen-announce
Subject:    [Xen-announce] Xen Security Advisory 212 (CVE-2017-7228) - x86: broken check in memory_exchange() pe
From:       Xen.org security team <security () xen ! org>
Date:       2017-04-04 12:37:14
Message-ID: E1cvNhy-0000Vj-CZ () xenbits ! xenproject ! org
[Download RAW message or body]

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

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

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 #4 (text/plain)]

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

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

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