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

List:       oss-security
Subject:    [oss-security] Xen Security Advisory 285 v3 (CVE-2019-17341) - race with pass-through device hotplug
From:       Xen.org security team <security () xen ! org>
Date:       2019-10-25 11:10:31
Message-ID: E1iNxUF-0002fv-DR () xenbits ! xenproject ! org
[Download RAW message or body]

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

            Xen Security Advisory CVE-2019-17341 / XSA-285
                              version 3

                 race with pass-through device hotplug

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

CVE assigned.

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

When adding a passed-through PCI device to a domain after it was already
started, IOMMU page tables may need constructing on the fly.  For PV
guests the decision whether a page ought to have a mapping is based on
whether the page is writable, to prevent IOMMU access to things like
page tables.  Writablility of a page may, however, change at any time.
Failure of the relevant code to respect this possible race may lead
to IOMMU mappings of, in particular, page tables, allowing the guest
to alter such page tables without Xen auditing the changes.

IMPACT
======

Malicious PV guests can escalate their privilege to that of the
hypervisor.

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

All versions of Xen are vulnerable.

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

Only x86 PV guests can exploit the vulnerability.  x86 HVM and PVH
guests cannot exploit the vulnerability.

Only guests which are assigned a device after domain creation can
exploit this vulnerability.  Guests which are not assigned devices, or
guests assigned devices at domain creation time, cannot exploit this
vulnerability.

MITIGATION
==========

Running only HVM or PVH guests avoids the vulnerability.

Assigning passed-through PCI devices to PV guests at domain creation
time also avoids the vulnerability.

CREDITS
=======

This issue was discovered by Jan Beulich of SUSE.

RESOLUTION
==========

Applying the appropriate attached patch resolves this issue.

xsa285.patch           xen-unstable
xsa285-4.11.patch      Xen 4.7.x - Xen 4.11.x

$ sha256sum xsa285*
0851a4a9120220e2b03eafaf94648077154b6a6f27c29055d3779ccad7684fce  xsa285.meta
9e96d3763158edde8d664c3e26761e63ca6f96bb921e0d7eb68351fe47499bde  xsa285.patch
38ec20b04e0a859abe9850803ae00a33e48591a9949e5287dfa3725f3bd179f3  xsa285-4.11.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/4UyVfoK9kFAl2y178MHHBncEB4ZW4u
b3JnAAoJEIP+FMlX6CvZnhUIALWg5ROzP7vpvNOEQDICm/A/AxjPLB6uHnj95bBJ
CxfLZPZyxUak9jmn8bJJrhJBNGS/RFUWrwWm+mHku8ywNKTcHkhGtweS8/GjuMeG
I7hhh/Ux39vs/kPWvy7uydMIMrcIsiG69NWXl6xWMGkcmcmlkJCAi2KHX20Jb5qi
Izy7swNoBFWuuGMaBTg8YJ+XfqQGonemzgviY01EHQqJo/2wPyJjgsbZzu6XlNJc
R3K9K4RDzjtemIEQps9CWA8ilEXxv6DIhVKBx0gNLIrJZPVEh2awLr5Ve2YZIdk6
N5hSP2LFyueDhmKvwrMnrrKF4XqHlfyIsW0l8TXwa/OUTVI=
=6noj
-----END PGP SIGNATURE-----

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

From: Jan Beulich <jbeulich@suse.com>
Subject: IOMMU/x86: fix type ref-counting race upon IOMMU page table construction

When arch_iommu_populate_page_table() gets invoked for an already
running guest, simply looking at page types once isn't enough, as they
may change at any time. Add logic to re-check the type after having
mapped the page, unmapping it again if needed.

This is XSA-285.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Tentatively-Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
v4: Re-write comment (use George's wording).
v3: Re-base.
v2: Re-base.

--- a/xen/drivers/passthrough/x86/iommu.c
+++ b/xen/drivers/passthrough/x86/iommu.c
@@ -70,6 +70,27 @@ int arch_iommu_populate_page_table(struc
                 rc = iommu_map(d, _dfn(gfn), _mfn(mfn), PAGE_ORDER_4K,
                                IOMMUF_readable | IOMMUF_writable,
                                &flush_flags);
+
+                /*
+                 * We may be working behind the back of a running guest, which
+                 * may change the type of a page at any time.  We can't prevent
+                 * this (for instance, by bumping the type count while mapping
+                 * the page) without causing legitimate guest type-change
+                 * operations to fail.  So after adding the page to the IOMMU,
+                 * check again to make sure this is still valid.  NB that the
+                 * writable entry in the iommu is harmless until later, when
+                 * the actual device gets assigned.
+                 */
+                if ( !rc && !is_hvm_domain(d) &&
+                     ((page->u.inuse.type_info & PGT_type_mask) !=
+                      PGT_writable_page) )
+                {
+                    rc = iommu_unmap(d, _dfn(gfn), PAGE_ORDER_4K, &flush_flags);
+                    /* If the type changed yet again, simply force a retry. */
+                    if ( !rc && ((page->u.inuse.type_info & PGT_type_mask) ==
+                                 PGT_writable_page) )
+                        rc = -ERESTART;
+                }
             }
             if ( rc )
             {

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

From: Jan Beulich <jbeulich@suse.com>
Subject: IOMMU/x86: fix type ref-counting race upon IOMMU page table construction

When arch_iommu_populate_page_table() gets invoked for an already
running guest, simply looking at page types once isn't enough, as they
may change at any time. Add logic to re-check the type after having
mapped the page, unmapping it again if needed.

This is XSA-285.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Tentatively-Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>

--- a/xen/drivers/passthrough/x86/iommu.c
+++ b/xen/drivers/passthrough/x86/iommu.c
@@ -68,6 +68,27 @@ int arch_iommu_populate_page_table(struct domain *d)
                 rc = hd->platform_ops->map_page(d, gfn, mfn,
                                                 IOMMUF_readable |
                                                 IOMMUF_writable);
+
+                /*
+                 * We may be working behind the back of a running guest, which
+                 * may change the type of a page at any time.  We can't prevent
+                 * this (for instance, by bumping the type count while mapping
+                 * the page) without causing legitimate guest type-change
+                 * operations to fail.  So after adding the page to the IOMMU,
+                 * check again to make sure this is still valid.  NB that the
+                 * writable entry in the iommu is harmless until later, when
+                 * the actual device gets assigned.
+                 */
+                if ( !rc && !is_hvm_domain(d) &&
+                     ((page->u.inuse.type_info & PGT_type_mask) !=
+                      PGT_writable_page) )
+                {
+                    rc = hd->platform_ops->unmap_page(d, gfn);
+                    /* If the type changed yet again, simply force a retry. */
+                    if ( !rc && ((page->u.inuse.type_info & PGT_type_mask) ==
+                                 PGT_writable_page) )
+                        rc = -ERESTART;
+                }
             }
             if ( rc )
             {


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

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