All of lore.kernel.org
 help / color / mirror / Atom feed
* Xen Security Advisory 99 - unexpected pitfall in xenaccess API
@ 2014-06-17 13:13 Andres Lagar Cavilla
  2014-06-17 13:24 ` Steven Haigh
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Andres Lagar Cavilla @ 2014-06-17 13:13 UTC (permalink / raw)
  To: xen-devel, security, xen-announce, oss-security


[-- Attachment #1.1: Type: text/plain, Size: 4546 bytes --]

>
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
>                     Xen Security Advisory XSA-99
>                              version 2
>
>                  unexpected pitfall in xenaccess API
>
> UPDATES IN VERSION 2
> ====================
>
> Public Release.
>
> Added note regarding CVE.
>
> ISSUE DESCRIPTION
> =================
>
> A test/example program, for exercising the Xen memaccess API, does not
> take all necessary precautions against hostile guest behaviour.
>
> As a result, software developers using it as an example or template
> might have written and deployed vulnerable code.
>
How?

I've looked at the patch. It's the refactor proposed in a separate thread
by Dushyant Behl, lifted up a level. Obviously useful, +2.

But fundamentally, how is this a vulnerability? Since the dawn of time
guests can poke at the qemu and PV frontend rings. So self DoS, check. But,
privilege escalation?

Is this predicated on the potential (lack of) software quality of the
xenaccess backends? That's a fair argument, but a different story.

I am puzzled how this is an XSA that addresses "privilege escalation".

Thanks
Andres

>
> See the patch for technical details of the problem.
>
> IMPACT
> ======
>
> Deployments of software inspired by, or derived from,
> xen.git/tools/tests/xen-access/xen-access.c, may be vulnerable to
> privilege escalation by a malicious guest administrator.
>
> xen-access is a test/example program and is not, without modification,
> useful in production.  It is not built or installed by default.
>
> VULNERABLE SYSTEMS
> ==================
>
> Unmodified Xen installations (including installations as provided by
> typical Free Software distributions) are not vulnerable.
>
> The following toolstacks/libraries do not use memaccess, so systems
> using Xen only via the following are not vulnerable:
>     libxl; xl; xend; xm; libvirt
>
> In general, Xen installations which make no use of the Xen memory
> access API (xc_mem_access_..., "XENMEM_access_...",
> XEN_DOMCTL_MEM_EVENT_OP_ACCESS_ENABLE) are not vulnerable.
>
> Systems using the Xen hypervisor 4.1 or earlier are not vulnerable.
> ARM systems are not vulnerable.  AMD systems are not vulnerable.
> Intel x86 systems without EPT are not vulnerable.
>
> Software developers who have based their efforts on xen-access.c may
> have constructed vulnerable systems.  Such developers should examine
> their software, and communicate with their own downstreams, as
> applicable.
>
> Users of Xen-derived systems, whose vulnerability is not excluded
> above, should consult their vendor for information about the
> applicability of this vulnerability.
>
> MITIGATION
> ==========
>
> Disabling whatever functionality uses the memaccess API will avoid the
> vulnerability.
>
> NOTE REGARDING CVE
> ==================
>
> The CVE assignment team at the MITRE CVE Numbering Authority have told
> us that type of issue is typically considered site-specific and is not
> eligible for a CVE ID:
>
>  The scope of CVE does not include issues where a vulnerable program
>  can be present after a customer modifies shipped source code or
>  modifies the build process. The primary purpose of this guideline is
>  to avoid CVE assignments where, for example, the vulnerability exists
>  only when a customer enables experimental code and then recompiles. A
>  secondary purpose of this guideline is to avoid CVE assignments for
>  example code that wasn't intended to be used as-is.
>
> Software developers who have based production code on xen-access.c
> should obtain their own CVE number(s).
>
> CREDITS
> =======
>
> This vulnerability was discovered by Ian Campbell of Citrix.
>
> RESOLUTION
> ==========
>
> The attached patch repairs the test/example utility provided in the
> Xen Project source tree.
>
> To resolve the issue in production software, appropriate changes
> will have to be be made by its developers.
>
> $ sha256sum xsa99*.patch
> d6496699d9952bbfe1cd86e0ba84182e455a5dc4626654d387f92390d9680cd4
>  xsa99.patch
> $
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.12 (GNU/Linux)
>
> iQEcBAEBAgAGBQJToCn/AAoJEIP+FMlX6CvZBp8H/Az39oLQiAIyrZRD+IktvGuB
> mCLRcoyTJxxfE+9bAFltypelGNwq5NT/JUwub82whapbPW/e/rtGbln43FkdkoLu
> oFlddcteOzJMTLsLXxe50zrgb4QaUEt4lxQ2zEyFpL6PYz32pO24NLK8QzG480Ol
> 4u1UlBJeYM61Z4JPuCy0h5vMy0eU6G3yry6B09s4Dmdfvd6AU7BprFT4/aW+noQ0
> 84w11iL8Y53ddnidTgaXNkyvcq+5m57RL9uHvrRz7mViqhazkVkxGZHVKsUYuRPb
> wkBpSaa+cJkeF8AnDue/QuW0pWYpfrPoniD86SwgzsYYj5bN0EnQ4CTzVIAx284=
> =9myT
> -----END PGP SIGNATURE-----
>
>

[-- Attachment #1.2: Type: text/html, Size: 5458 bytes --]

[-- Attachment #2: Type: text/plain, Size: 126 bytes --]

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

^ permalink raw reply	[flat|nested] 9+ messages in thread
* Xen Security Advisory 99 - unexpected pitfall in xenaccess API
@ 2014-06-17 12:16 Xen.org security team
  0 siblings, 0 replies; 9+ messages in thread
From: Xen.org security team @ 2014-06-17 12:16 UTC (permalink / raw)
  To: xen-announce, xen-devel, xen-users, oss-security; +Cc: Xen.org security team

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

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

                    Xen Security Advisory XSA-99
                             version 2

                 unexpected pitfall in xenaccess API

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

Public Release.

Added note regarding CVE.

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

A test/example program, for exercising the Xen memaccess API, does not
take all necessary precautions against hostile guest behaviour.

As a result, software developers using it as an example or template
might have written and deployed vulnerable code.

See the patch for technical details of the problem.

IMPACT
======

Deployments of software inspired by, or derived from,
xen.git/tools/tests/xen-access/xen-access.c, may be vulnerable to
privilege escalation by a malicious guest administrator.

xen-access is a test/example program and is not, without modification,
useful in production.  It is not built or installed by default.

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

Unmodified Xen installations (including installations as provided by
typical Free Software distributions) are not vulnerable.

The following toolstacks/libraries do not use memaccess, so systems
using Xen only via the following are not vulnerable:
    libxl; xl; xend; xm; libvirt

In general, Xen installations which make no use of the Xen memory
access API (xc_mem_access_..., "XENMEM_access_...",
XEN_DOMCTL_MEM_EVENT_OP_ACCESS_ENABLE) are not vulnerable.

Systems using the Xen hypervisor 4.1 or earlier are not vulnerable.
ARM systems are not vulnerable.  AMD systems are not vulnerable.
Intel x86 systems without EPT are not vulnerable.

Software developers who have based their efforts on xen-access.c may
have constructed vulnerable systems.  Such developers should examine
their software, and communicate with their own downstreams, as
applicable.

Users of Xen-derived systems, whose vulnerability is not excluded
above, should consult their vendor for information about the
applicability of this vulnerability.

MITIGATION
==========

Disabling whatever functionality uses the memaccess API will avoid the
vulnerability.

NOTE REGARDING CVE
==================

The CVE assignment team at the MITRE CVE Numbering Authority have told
us that type of issue is typically considered site-specific and is not
eligible for a CVE ID:

 The scope of CVE does not include issues where a vulnerable program
 can be present after a customer modifies shipped source code or
 modifies the build process. The primary purpose of this guideline is
 to avoid CVE assignments where, for example, the vulnerability exists
 only when a customer enables experimental code and then recompiles. A
 secondary purpose of this guideline is to avoid CVE assignments for
 example code that wasn't intended to be used as-is.

Software developers who have based production code on xen-access.c
should obtain their own CVE number(s).

CREDITS
=======

This vulnerability was discovered by Ian Campbell of Citrix.

RESOLUTION
==========

The attached patch repairs the test/example utility provided in the
Xen Project source tree.

To resolve the issue in production software, appropriate changes
will have to be be made by its developers.

$ sha256sum xsa99*.patch
d6496699d9952bbfe1cd86e0ba84182e455a5dc4626654d387f92390d9680cd4  xsa99.patch
$
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (GNU/Linux)

iQEcBAEBAgAGBQJToCn/AAoJEIP+FMlX6CvZBp8H/Az39oLQiAIyrZRD+IktvGuB
mCLRcoyTJxxfE+9bAFltypelGNwq5NT/JUwub82whapbPW/e/rtGbln43FkdkoLu
oFlddcteOzJMTLsLXxe50zrgb4QaUEt4lxQ2zEyFpL6PYz32pO24NLK8QzG480Ol
4u1UlBJeYM61Z4JPuCy0h5vMy0eU6G3yry6B09s4Dmdfvd6AU7BprFT4/aW+noQ0
84w11iL8Y53ddnidTgaXNkyvcq+5m57RL9uHvrRz7mViqhazkVkxGZHVKsUYuRPb
wkBpSaa+cJkeF8AnDue/QuW0pWYpfrPoniD86SwgzsYYj5bN0EnQ4CTzVIAx284=
=9myT
-----END PGP SIGNATURE-----

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

From: Aravindh Puthiyaparambil <aravindp@cisco.com>
Date: Tue May 20 16:35:44 2014 -0700

mem_access: Add helper API to setup ring and enable mem_access

tools/libxc: Add helper function to setup ring for mem events
This patch adds a helper function that maps the ring, enables mem_event
and removes the ring from the guest physmap while the domain is paused.
This can be used by all mem_events but is only enabled for mem_access at
the moment.

tests/xen-access: Use helper API to setup ring and enable mem_access
Prior to this patch, xen-access was setting up the ring page in a way
that would give a malicous guest a window to write in to the shared ring
page. This patch fixes this by using the helper API that does it safely
on behalf of xen-access.

This is XSA-99.

Signed-off-by: Aravindh Puthiyaparambil <aravindp@cisco.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>

diff --git a/tools/libxc/xc_mem_access.c b/tools/libxc/xc_mem_access.c
index f436e69..461f0e9 100644
--- a/tools/libxc/xc_mem_access.c
+++ b/tools/libxc/xc_mem_access.c
@@ -24,19 +24,9 @@
 #include "xc_private.h"
 #include <xen/memory.h>
 
-int xc_mem_access_enable(xc_interface *xch, domid_t domain_id,
-                         uint32_t *port)
+void *xc_mem_access_enable(xc_interface *xch, domid_t domain_id, uint32_t *port)
 {
-    if ( !port )
-    {
-        errno = EINVAL;
-        return -1;
-    }
-
-    return xc_mem_event_control(xch, domain_id,
-                                XEN_DOMCTL_MEM_EVENT_OP_ACCESS_ENABLE,
-                                XEN_DOMCTL_MEM_EVENT_OP_ACCESS,
-                                port);
+    return xc_mem_event_enable(xch, domain_id, HVM_PARAM_ACCESS_RING_PFN, port);
 }
 
 int xc_mem_access_disable(xc_interface *xch, domid_t domain_id)
diff --git a/tools/libxc/xc_mem_event.c b/tools/libxc/xc_mem_event.c
index d43a0af..be7c63d 100644
--- a/tools/libxc/xc_mem_event.c
+++ b/tools/libxc/xc_mem_event.c
@@ -56,3 +56,118 @@ int xc_mem_event_memop(xc_interface *xch, domid_t domain_id,
     return do_memory_op(xch, mode, &meo, sizeof(meo));
 }
 
+void *xc_mem_event_enable(xc_interface *xch, domid_t domain_id, int param,
+                          uint32_t *port)
+{
+    void *ring_page = NULL;
+    unsigned long ring_pfn, mmap_pfn;
+    unsigned int op, mode;
+    int rc1, rc2, saved_errno;
+
+    if ( !port )
+    {
+        errno = EINVAL;
+        return NULL;
+    }
+
+    /* Pause the domain for ring page setup */
+    rc1 = xc_domain_pause(xch, domain_id);
+    if ( rc1 != 0 )
+    {
+        PERROR("Unable to pause domain\n");
+        return NULL;
+    }
+
+    /* Get the pfn of the ring page */
+    rc1 = xc_get_hvm_param(xch, domain_id, param, &ring_pfn);
+    if ( rc1 != 0 )
+    {
+        PERROR("Failed to get pfn of ring page\n");
+        goto out;
+    }
+
+    mmap_pfn = ring_pfn;
+    ring_page = xc_map_foreign_batch(xch, domain_id, PROT_READ | PROT_WRITE,
+                                     &mmap_pfn, 1);
+    if ( mmap_pfn & XEN_DOMCTL_PFINFO_XTAB )
+    {
+        /* Map failed, populate ring page */
+        rc1 = xc_domain_populate_physmap_exact(xch, domain_id, 1, 0, 0,
+                                              &ring_pfn);
+        if ( rc1 != 0 )
+        {
+            PERROR("Failed to populate ring pfn\n");
+            goto out;
+        }
+
+        mmap_pfn = ring_pfn;
+        ring_page = xc_map_foreign_batch(xch, domain_id, PROT_READ | PROT_WRITE,
+                                         &mmap_pfn, 1);
+        if ( mmap_pfn & XEN_DOMCTL_PFINFO_XTAB )
+        {
+            PERROR("Could not map the ring page\n");
+            goto out;
+        }
+    }
+
+    switch ( param )
+    {
+    case HVM_PARAM_PAGING_RING_PFN:
+        op = XEN_DOMCTL_MEM_EVENT_OP_PAGING_ENABLE;
+        mode = XEN_DOMCTL_MEM_EVENT_OP_PAGING;
+        break;
+
+    case HVM_PARAM_ACCESS_RING_PFN:
+        op = XEN_DOMCTL_MEM_EVENT_OP_ACCESS_ENABLE;
+        mode = XEN_DOMCTL_MEM_EVENT_OP_ACCESS;
+        break;
+
+    case HVM_PARAM_SHARING_RING_PFN:
+        op = XEN_DOMCTL_MEM_EVENT_OP_SHARING_ENABLE;
+        mode = XEN_DOMCTL_MEM_EVENT_OP_SHARING;
+        break;
+
+    /*
+     * This is for the outside chance that the HVM_PARAM is valid but is invalid
+     * as far as mem_event goes.
+     */
+    default:
+        errno = EINVAL;
+        rc1 = -1;
+        goto out;
+    }
+
+    rc1 = xc_mem_event_control(xch, domain_id, op, mode, port);
+    if ( rc1 != 0 )
+    {
+        PERROR("Failed to enable mem_event\n");
+        goto out;
+    }
+
+    /* Remove the ring_pfn from the guest's physmap */
+    rc1 = xc_domain_decrease_reservation_exact(xch, domain_id, 1, 0, &ring_pfn);
+    if ( rc1 != 0 )
+        PERROR("Failed to remove ring page from guest physmap");
+
+ out:
+    saved_errno = errno;
+
+    rc2 = xc_domain_unpause(xch, domain_id);
+    if ( rc1 != 0 || rc2 != 0 )
+    {
+        if ( rc2 != 0 )
+        {
+            if ( rc1 == 0 )
+                saved_errno = errno;
+            PERROR("Unable to unpause domain");
+        }
+
+        if ( ring_page )
+            munmap(ring_page, XC_PAGE_SIZE);
+        ring_page = NULL;
+
+        errno = saved_errno;
+    }
+
+    return ring_page;
+}
diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h
index 02129f7..34678d8 100644
--- a/tools/libxc/xenctrl.h
+++ b/tools/libxc/xenctrl.h
@@ -2023,6 +2023,12 @@ int xc_mem_event_control(xc_interface *xch, domid_t domain_id, unsigned int op,
 int xc_mem_event_memop(xc_interface *xch, domid_t domain_id, 
                         unsigned int op, unsigned int mode,
                         uint64_t gfn, void *buffer);
+/*
+ * Enables mem_event and returns the mapped ring page indicated by param.
+ * param can be HVM_PARAM_PAGING/ACCESS/SHARING_RING_PFN
+ */
+void *xc_mem_event_enable(xc_interface *xch, domid_t domain_id, int param,
+                          uint32_t *port);
 
 /** 
  * Mem paging operations.
@@ -2043,7 +2049,13 @@ int xc_mem_paging_load(xc_interface *xch, domid_t domain_id,
  * Access tracking operations.
  * Supported only on Intel EPT 64 bit processors.
  */
-int xc_mem_access_enable(xc_interface *xch, domid_t domain_id, uint32_t *port);
+
+/*
+ * Enables mem_access and returns the mapped ring page.
+ * Will return NULL on error.
+ * Caller has to unmap this page when done.
+ */
+void *xc_mem_access_enable(xc_interface *xch, domid_t domain_id, uint32_t *port);
 int xc_mem_access_disable(xc_interface *xch, domid_t domain_id);
 int xc_mem_access_resume(xc_interface *xch, domid_t domain_id);
 
diff --git a/tools/tests/xen-access/xen-access.c b/tools/tests/xen-access/xen-access.c
index 0a84bd5..572ab63 100644
--- a/tools/tests/xen-access/xen-access.c
+++ b/tools/tests/xen-access/xen-access.c
@@ -223,7 +223,6 @@ xenaccess_t *xenaccess_init(xc_interface **xch_r, domid_t domain_id)
     xenaccess_t *xenaccess = 0;
     xc_interface *xch;
     int rc;
-    unsigned long ring_pfn, mmap_pfn;
 
     xch = xc_interface_open(NULL, NULL, 0);
     if ( !xch )
@@ -245,40 +244,12 @@ xenaccess_t *xenaccess_init(xc_interface **xch_r, domid_t domain_id)
     /* Initialise lock */
     mem_event_ring_lock_init(&xenaccess->mem_event);
 
-    /* Map the ring page */
-    xc_get_hvm_param(xch, xenaccess->mem_event.domain_id, 
-                        HVM_PARAM_ACCESS_RING_PFN, &ring_pfn);
-    mmap_pfn = ring_pfn;
-    xenaccess->mem_event.ring_page = 
-        xc_map_foreign_batch(xch, xenaccess->mem_event.domain_id, 
-                                PROT_READ | PROT_WRITE, &mmap_pfn, 1);
-    if ( mmap_pfn & XEN_DOMCTL_PFINFO_XTAB )
-    {
-        /* Map failed, populate ring page */
-        rc = xc_domain_populate_physmap_exact(xenaccess->xc_handle, 
-                                              xenaccess->mem_event.domain_id,
-                                              1, 0, 0, &ring_pfn);
-        if ( rc != 0 )
-        {
-            PERROR("Failed to populate ring gfn\n");
-            goto err;
-        }
-
-        mmap_pfn = ring_pfn;
-        xenaccess->mem_event.ring_page = 
-            xc_map_foreign_batch(xch, xenaccess->mem_event.domain_id, 
-                                    PROT_READ | PROT_WRITE, &mmap_pfn, 1);
-        if ( mmap_pfn & XEN_DOMCTL_PFINFO_XTAB )
-        {
-            PERROR("Could not map the ring page\n");
-            goto err;
-        }
-    }
-
-    /* Initialise Xen */
-    rc = xc_mem_access_enable(xenaccess->xc_handle, xenaccess->mem_event.domain_id,
-                             &xenaccess->mem_event.evtchn_port);
-    if ( rc != 0 )
+    /* Enable mem_access */
+    xenaccess->mem_event.ring_page =
+            xc_mem_access_enable(xenaccess->xc_handle,
+                                 xenaccess->mem_event.domain_id,
+                                 &xenaccess->mem_event.evtchn_port);
+    if ( xenaccess->mem_event.ring_page == NULL )
     {
         switch ( errno ) {
             case EBUSY:
@@ -288,7 +259,7 @@ xenaccess_t *xenaccess_init(xc_interface **xch_r, domid_t domain_id)
                 ERROR("EPT not supported for this guest");
                 break;
             default:
-                perror("Error initialising shared page");
+                perror("Error enabling mem_access");
                 break;
         }
         goto err;
@@ -322,11 +293,6 @@ xenaccess_t *xenaccess_init(xc_interface **xch_r, domid_t domain_id)
                    (mem_event_sring_t *)xenaccess->mem_event.ring_page,
                    XC_PAGE_SIZE);
 
-    /* Now that the ring is set, remove it from the guest's physmap */
-    if ( xc_domain_decrease_reservation_exact(xch, 
-                    xenaccess->mem_event.domain_id, 1, 0, &ring_pfn) )
-        PERROR("Failed to remove ring from guest physmap");
-
     /* Get domaininfo */
     xenaccess->domain_info = malloc(sizeof(xc_domaininfo_t));
     if ( xenaccess->domain_info == NULL )

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

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

^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2014-06-17 18:23 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-06-17 13:13 Xen Security Advisory 99 - unexpected pitfall in xenaccess API Andres Lagar Cavilla
2014-06-17 13:24 ` Steven Haigh
2014-06-17 13:40   ` Ian Campbell
     [not found]     ` <CAGU+autpif3iTpZ4BGNarXZksXAm37Owq5hmDTG++=aMBYaC9w@mail.gmail.com>
2014-06-17 18:23       ` Aravindh Puthiyaparambil (aravindp)
2014-06-17 13:36 ` Ian Campbell
     [not found] ` <1403012214.16844.111.camel@kazak.uk.xensource.com>
2014-06-17 13:50   ` Andres Lagar Cavilla
2014-06-17 13:57     ` Ian Campbell
2014-06-17 14:01       ` Andres Lagar Cavilla
  -- strict thread matches above, loose matches on Subject: below --
2014-06-17 12:16 Xen.org security team

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.