Xen Security Advisory 160 (CVE-2015-8341) - libxl leak of pv kernel and initrd on error

Xen.org security team <[email protected]>
Newsgroups gmane.comp.emulators.xen.announce
Message-ID <E1a6GyL-0003v0-Cb__16206.4381562688$1449576589$gmane$org@xenbits.xen.org>
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

            Xen Security Advisory CVE-2015-8341 / XSA-160
                              version 3

              libxl leak of pv kernel and initrd on error

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

Public release.

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

When constructing a guest which is configured to use a PV bootloader
which runs as a userspace process in the toolstack domain
(e.g. pygrub) libxl creates a mapping of the files to be used as
kernel and initial ramdisk when building the guest domain.

However if building the domain subsequently fails these mappings would
not be released leading to a leak of virtual address space in the
calling process, as well as preventing the recovery of the temporary
disk files containing the kernel and initial ramdisk.

IMPACT
======

For toolstacks which manage multiple domains within the same process,
an attacker who is able to repeatedly start a suitable domain (or many
such domains) can cause an out-of-memory condition in the toolstack
process, leading to a denial of service.

Under the same circumstances an attacker can also cause files to
accumulate on the toolstack domain filesystem (usually under /var in
dom0) used to temporarily store the kernel and initial ramdisk,
perhaps leading to a denial of service against arbitrary other
services using that filesystem.

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

Both ARM and x86 systems using a libxl based toolstack are potentially
vulnerable.

Only libxl-based toolstacks which manage multiple domains in the same
process (such as `libvirt') are vulnerable.

libxl-based toolstacks which manage only a single domain per process
and which exit on failure to create a domain (such as `xl') are not
vulnerable.

Toolstacks not using libxl are not vulnerable to this issue.

Only domains configured to use a PV bootloader in the toolstack domain
(e.g. pygrub) will expose this issue.  Domains configured to use
pvgrub (a totally different program) are not vulnerable.

x86 HVM domains are not vulnerable.

Systems where the kernel and initial ramdisk are provided by the host
administrator from files in domain 0 are not vulnerable.

Xen versions 4.1.x and later are vulnerable.

MITIGATION
==========

Avoiding the use of the PV bootloader mechanisms which run as
processes in the toolstack domain (pygrub), either by providing
kernels directly from the toolstack domain or using a PV bootloader
which runs in guest context (such as pvgrub) will prevent exposure of
this issue.

CREDITS
=======

This issue was discovered by George Dunlap of Citrix.

RESOLUTION
==========

Applying the appropriate attached patch resolves this issue.

xsa160.patch               xen-unstable
xsa160-4.6.patch           Xen 4.5.x, 4.6.x
xsa160-4.4.patch           Xen 4.3.x, 4.4.x

$ sha256sum xsa160*
470811aeead5e942d6fedad5b4e21bee85f2160b022bcab315520014b6aa39a6  xsa160.patch
d0ce9e3c2b951ac3d25da4a0f6f232b13980625a249ed9c4cd6e9484721943a5  xsa160-4.4.patch
40362873b7fa2c1450596ef9ea23c73f80608b77ca50b89e62daf46c131fcee6  xsa160-4.6.patch
$

DEPLOYMENT DURING EMBARGO
=========================

Deployment of the patch described above (or others which are
substantially similar) is permitted during the embargo, even on
public-facing systems with untrusted guest users and administrators.

However deployment of the mitigations described above is not permitted
(except where all the affected systems and VMs are administered and
used only by organisations which are members of the Xen Project
Security Issues Predisclosure List).  Specifically, deployment on
public cloud systems is NOT permitted.

This is because such a change to the bootloader arrangements of a PV
guest would be a user-visible change which could lead to the
rediscovery of the vulnerability.

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.4.12 (GNU/Linux)

iQEcBAEBAgAGBQJWZr8JAAoJEIP+FMlX6CvZfEYH/Rg7X9HdB+937h81tq30nrkE
/PazyPDB8DprHL0X/IjPEQFvGOazCf45uzSzkrPXaFwu27yhbAxx/m8s94FxUjWb
EiWwYKsb0Gh9OBejRkgiB3VMQmySWqkcjzUR1f2hk4iJ3yX8q2peRECK/Ba9aYPu
lHN9aycnh1ORPmWPUUo8cMFhRVag1P5E77mqrxXo2nfed23xDA5GeZceg8XoT67n
T2m59xAEwrSrHypb/XESuwtEU67CnowRcxlH7Z3EEk+ljvxOBvdovNp0yztOtArK
EnV3UAwM+YMXvoYB4YZUQ/q9tZ1dIgyeTosOSoNHI471lBYL9QTlO22bc4+qKCE=
=IjJr
-----END PGP SIGNATURE-----

_______________________________________________
Xen-announce mailing list
[email protected]
http://lists.xen.org/xen-announce
xsa160.patch (application/octet-stream, 2.7 KB)
From 43a10fecd6f4a9d8adf9f5d85e3d5e7187e2d54a Mon Sep 17 00:00:00 2001
From: Ian Jackson <[email protected]>
Date: Wed, 18 Nov 2015 15:34:54 +0000
Subject: [PATCH] libxl: Fix bootloader-related virtual memory leak on pv
 build failure

The bootloader may call libxl__file_reference_map(), which mmap's the
pv_kernel and pv_ramdisk into process memory.  This was only unmapped,
however, on the success path of libxl__build_pv().  If there were a
failure anywhere between libxl_bootloader.c:parse_bootloader_result()
and the end of libxl__build_pv(), the calls to
libxl__file_reference_unmap() would be skipped, leaking the mapped
virtual memory.

Ideally this would be fixed by adding the unmap calls to the
destruction path for libxl__domain_build_state.  Unfortunately the
lifetime of the libxl__domain_build_state is opaque, and it doesn't
have a proper destruction path.  But, the only thing in it that isn't
from the gc are these bootloader references, and they are only ever
set for one libxl__domain_build_state, the one which is
libxl__domain_create_state.build_state.

So we can clean up in the exit path from libxl__domain_create_*, which
always comes through domcreate_complete.

Remove the now-redundant unmaps in libxl__build_pv's success path.

This is XSA-160.

Signed-off-by: George Dunlap <[email protected]>
Signed-off-by: Ian Jackson <[email protected]>
Tested-by: George Dunlap <[email protected]>
Acked-by: Ian Campbell <[email protected]>
---
 tools/libxl/libxl_create.c |    3 +++
 tools/libxl/libxl_dom.c    |    3 ---
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index f0fee00..cebf90e 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -1480,6 +1480,9 @@ static void domcreate_complete(libxl__egc *egc,
     libxl_domain_config *const d_config = dcs->guest_config;
     libxl_domain_config *d_config_saved = &dcs->guest_config_saved;
 
+    libxl__file_reference_unmap(&dcs->build_state.pv_kernel);
+    libxl__file_reference_unmap(&dcs->build_state.pv_ramdisk);
+
     if (!rc && d_config->b_info.exec_ssidref)
         rc = xc_flask_relabel_domain(CTX->xch, dcs->guest_domid, d_config->b_info.exec_ssidref);
 
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index 44d481b..8872197 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -767,9 +767,6 @@ int libxl__build_pv(libxl__gc *gc, uint32_t domid,
         state->store_mfn = xc_dom_p2m(dom, dom->xenstore_pfn);
     }
 
-    libxl__file_reference_unmap(&state->pv_kernel);
-    libxl__file_reference_unmap(&state->pv_ramdisk);
-
     ret = 0;
 out:
     xc_dom_release(dom);
-- 
1.7.10.4
xsa160-4.4.patch (application/octet-stream, 2.6 KB)
From 7f9fd14c80b71b4abbca36f2747d2e75dfebc289 Mon Sep 17 00:00:00 2001
From: Ian Jackson <[email protected]>
Date: Wed, 18 Nov 2015 15:34:54 +0000
Subject: [PATCH] libxl: Fix bootloader-related virtual memory leak on pv
 build failure

The bootloader may call libxl__file_reference_map(), which mmap's the
pv_kernel and pv_ramdisk into process memory.  This was only unmapped,
however, on the success path of libxl__build_pv().  If there were a
failure anywhere between libxl_bootloader.c:parse_bootloader_result()
and the end of libxl__build_pv(), the calls to
libxl__file_reference_unmap() would be skipped, leaking the mapped
virtual memory.

Ideally this would be fixed by adding the unmap calls to the
destruction path for libxl__domain_build_state.  Unfortunately the
lifetime of the libxl__domain_build_state is opaque, and it doesn't
have a proper destruction path.  But, the only thing in it that isn't
from the gc are these bootloader references, and they are only ever
set for one libxl__domain_build_state, the one which is
libxl__domain_create_state.build_state.

So we can clean up in the exit path from libxl__domain_create_*, which
always comes through domcreate_complete.

Remove the now-redundant unmaps in libxl__build_pv's success path.

This is XSA-160.

Signed-off-by: George Dunlap <[email protected]>
Signed-off-by: Ian Jackson <[email protected]>
Tested-by: George Dunlap <[email protected]>
Acked-by: Ian Campbell <[email protected]>
---
 tools/libxl/libxl_create.c |    3 +++
 tools/libxl/libxl_dom.c    |    3 ---
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index e3350d5..5292c15 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -1295,6 +1295,9 @@ static void domcreate_complete(libxl__egc *egc,
     STATE_AO_GC(dcs->ao);
     libxl_domain_config *const d_config = dcs->guest_config;
 
+    libxl__file_reference_unmap(&dcs->build_state.pv_kernel);
+    libxl__file_reference_unmap(&dcs->build_state.pv_ramdisk);
+
     if (!rc && d_config->b_info.exec_ssidref)
         rc = xc_flask_relabel_domain(CTX->xch, dcs->guest_domid, d_config->b_info.exec_ssidref);
 
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index 52bc01a..978a1eb 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -451,9 +451,6 @@ int libxl__build_pv(libxl__gc *gc, uint32_t domid,
         state->store_mfn = xc_dom_p2m_host(dom, dom->xenstore_pfn);
     }
 
-    libxl__file_reference_unmap(&state->pv_kernel);
-    libxl__file_reference_unmap(&state->pv_ramdisk);
-
     ret = 0;
 out:
     xc_dom_release(dom);
-- 
1.7.10.4
xsa160-4.6.patch (application/octet-stream, 2.7 KB)
From adcbd15b1aec8367f790774c998db199c9b577bf Mon Sep 17 00:00:00 2001
From: Ian Jackson <[email protected]>
Date: Wed, 18 Nov 2015 15:34:54 +0000
Subject: [PATCH] libxl: Fix bootloader-related virtual memory leak on pv
 build failure

The bootloader may call libxl__file_reference_map(), which mmap's the
pv_kernel and pv_ramdisk into process memory.  This was only unmapped,
however, on the success path of libxl__build_pv().  If there were a
failure anywhere between libxl_bootloader.c:parse_bootloader_result()
and the end of libxl__build_pv(), the calls to
libxl__file_reference_unmap() would be skipped, leaking the mapped
virtual memory.

Ideally this would be fixed by adding the unmap calls to the
destruction path for libxl__domain_build_state.  Unfortunately the
lifetime of the libxl__domain_build_state is opaque, and it doesn't
have a proper destruction path.  But, the only thing in it that isn't
from the gc are these bootloader references, and they are only ever
set for one libxl__domain_build_state, the one which is
libxl__domain_create_state.build_state.

So we can clean up in the exit path from libxl__domain_create_*, which
always comes through domcreate_complete.

Remove the now-redundant unmaps in libxl__build_pv's success path.

This is XSA-160.

Signed-off-by: George Dunlap <[email protected]>
Signed-off-by: Ian Jackson <[email protected]>
Tested-by: George Dunlap <[email protected]>
Acked-by: Ian Campbell <[email protected]>
---
 tools/libxl/libxl_create.c |    3 +++
 tools/libxl/libxl_dom.c    |    3 ---
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index f5771da..278b9ed 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -1484,6 +1484,9 @@ static void domcreate_complete(libxl__egc *egc,
     libxl_domain_config *const d_config = dcs->guest_config;
     libxl_domain_config *d_config_saved = &dcs->guest_config_saved;
 
+    libxl__file_reference_unmap(&dcs->build_state.pv_kernel);
+    libxl__file_reference_unmap(&dcs->build_state.pv_ramdisk);
+
     if (!rc && d_config->b_info.exec_ssidref)
         rc = xc_flask_relabel_domain(CTX->xch, dcs->guest_domid, d_config->b_info.exec_ssidref);
 
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index 8019f4e..2da3ac4 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -750,9 +750,6 @@ int libxl__build_pv(libxl__gc *gc, uint32_t domid,
         state->store_mfn = xc_dom_p2m_host(dom, dom->xenstore_pfn);
     }
 
-    libxl__file_reference_unmap(&state->pv_kernel);
-    libxl__file_reference_unmap(&state->pv_ramdisk);
-
     ret = 0;
 out:
     xc_dom_release(dom);
-- 
1.7.10.4
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.