Xen Security Advisory 180 (CVE-2014-3672) - Unrestricted qemu logging
Xen.org security team <[email protected]>
| Newsgroups | gmane.comp.emulators.xen.announce |
|---|---|
| Message-ID | <E1b4tME-0003x1-2c__28200.6279485815$1464023896$gmane$org@xenbits.xenproject.org> |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Xen Security Advisory CVE-2014-3672 / XSA-180
Unrestricted qemu logging
ISSUE DESCRIPTION
=================
When the libxl toolstack launches qemu for HVM guests, it pipes the
output of stderr to a file in /var/log/xen. This output is not
rate-limited in any way. The guest can easily cause qemu to print
messages to stderr, causing this file to become arbitrarily large.
IMPACT
======
The disk containing the logfile can be exausted, possibly causing a
denial-of-service (DoS).
VULNERABLE SYSTEMS
==================
All versions of Xen are affected.
Only x86 systems are affected; ARM systems are not affected.
Only systems running HVM guests are affected; systems running only PV
guests are not affected.
Both qemu-upstream and qemu-traditional are affected.
MITIGATION
==========
Running only PV guests will avoid this vulnerability.
CREDITS
=======
This issue was discovered by Andrew Sorensen of leviathansecurity.com.
RESOLUTION
==========
Applying the appropriate attached patch resolves this issue.
The patches adopt a simple and rather crude approach which is
effective at resolving the security issue in the context of a Xen
device model. They may not be appropriate for adoption upstream or in
other contexts.
xsa180-qemut.patch qemu-xen-traditional (all supported versions)
xsa180-qemuu.patch qemu-xen (upstream) Xen unstable
$ sha256sum xsa180*
7733fd57868c4313c7c47ccde3aba21e9ed5002ee8a937b20997fb3d2282a5d7 xsa180-qemut.patch
7a92bbd3b6368f91e694400c8e850567972e14852e4f61fbb61cc3b7b98f14ef xsa180-qemuu.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.4.12 (GNU/Linux)
iQEcBAEBAgAGBQJXQzkrAAoJEIP+FMlX6CvZjkYIAMJRhIzcKP7P8Q075WKw29e2
PpLFy+eOM/946SOnKxrN/1Pq+yYl5Jn1rN/TMRre4n6pYdGlGY/+MFa4N2tfKhBv
8dYcE2BMD9tbLi4SpbvoIMUtmLM1y0lVSmtHbMaw/zQDpT0uM1Kh+P0VjTeBADo/
PgRgePGfV7r+4nVjxjdSiNah8XAR5P/hoHNGOaM2kuIT19FwyDK7uQONE+HL2SdI
ccA+JAMZFlHs1/hcjeCLny7Soedy4GPfGfqUpu/zRkaaDmCkG1E+gfcox5S2myYc
Kogj7oiVWjRTcYh5cUOIfSmC4TDM8pqWnMmFftGShOvWqRJH3tUWt3TkaU669X8=
=SczG
-----END PGP SIGNATURE-----
_______________________________________________
Xen-announce mailing list
[email protected]
http://lists.xen.org/xen-announce
xsa180-qemut.patch
(application/octet-stream, 2.3 KB)
From 7490dab5c1a01b1623e9d87bdc653cb4f963dd8a Mon Sep 17 00:00:00 2001 From: Ian Jackson <[email protected]> Date: Thu, 19 May 2016 19:38:35 +0100 Subject: [PATCH] main loop: Big hammer to fix logfile disk DoS in Xen setups Each time round the main loop, we now fstat stderr. If it is too big, we dup2 /dev/null onto it. This is not a very pretty patch but it is very simple, easy to see that it's correct, and has a low risk of collateral damage. The limit is 1Mby by default but can be adjusted by setting a new environment variable. This fixes CVE-2014-3672. Signed-off-by: Ian Jackson <[email protected]> Tested-by: Ian Jackson <[email protected]> --- vl.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/vl.c b/vl.c index c864e7d..d7ef742 100644 --- a/vl.c +++ b/vl.c @@ -3752,6 +3752,50 @@ static void host_main_loop_wait(int *timeout) } #endif +static void check_cve_2014_3672_xen(void) +{ + static unsigned long limit = ~0UL; + const int fd = 2; + struct stat stab; + + if (limit == ~0UL) { + const char *s = getenv("XEN_QEMU_CONSOLE_LIMIT"); + /* XEN_QEMU_CONSOLE_LIMIT=0 means no limit */ + limit = s ? strtoul(s,0,0) : 1*1024*1024; + } + if (limit == 0) + return; + + int r = fstat(fd, &stab); + if (r) { + perror("fstat stderr (for CVE-2014-3672 check)"); + exit(-1); + } + if (!S_ISREG(stab.st_mode)) + return; + if (stab.st_size <= limit) + return; + + /* oh dear */ + fprintf(stderr,"\r\n" + "Closing stderr due to CVE-2014-3672 limit. " + " Set XEN_QEMU_CONSOLE_LIMIT to number of bytes to override," + " or 0 for no limit.\n"); + fflush(stderr); + + int nfd = open("/dev/null", O_WRONLY); + if (nfd < 0) { + perror("open /dev/null (for CVE-2014-3672 check)"); + exit(-1); + } + r = dup2(nfd, fd); + if (r != fd) { + perror("dup2 /dev/null (for CVE-2014-3672 check)"); + exit(-1); + } + close(nfd); +} + void main_loop_wait(int timeout) { IOHandlerRecord *ioh; @@ -3763,6 +3807,8 @@ void main_loop_wait(int timeout) host_main_loop_wait(&timeout); + check_cve_2014_3672_xen(); + /* poll any events */ /* XXX: separate device handlers from system ones */ nfds = -1; -- 1.7.10.4
xsa180-qemuu.patch
(application/octet-stream, 2.9 KB)
From f4ebdf08f3eaaf2026adeaee5b8e520b08bb5e11 Mon Sep 17 00:00:00 2001 From: Ian Jackson <[email protected]> Date: Thu, 19 May 2016 15:43:33 +0100 Subject: [PATCH] main loop: Big hammer to fix logfile disk DoS in Xen setups Each time round the main loop, we now fstat stderr. If it is too big, we dup2 /dev/null onto it. This is not a very pretty patch but it is very simple, easy to see that it's correct, and has a low risk of collateral damage. The limit is 1Mby by default but can be adjusted by setting a new environment variable. This fixes CVE-2014-3672. Signed-off-by: Ian Jackson <[email protected]> Tested-by: Ian Jackson <[email protected]> --- v2: Make it actually compile. Fix a typo in the message. Move the check_cve_2014_3672_xen up in the file, so that we can: Call check_cve_2014_3672_xen in the other copy of the main loop (!) --- main-loop.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/main-loop.c b/main-loop.c index 3997043..4ac089e 100644 --- a/main-loop.c +++ b/main-loop.c @@ -164,6 +164,50 @@ int qemu_init_main_loop(Error **errp) return 0; } +static void check_cve_2014_3672_xen(void) +{ + static unsigned long limit = ~0UL; + const int fd = 2; + struct stat stab; + + if (limit == ~0UL) { + const char *s = getenv("XEN_QEMU_CONSOLE_LIMIT"); + /* XEN_QEMU_CONSOLE_LIMIT=0 means no limit */ + limit = s ? strtoul(s,0,0) : 1*1024*1024; + } + if (limit == 0) + return; + + int r = fstat(fd, &stab); + if (r) { + perror("fstat stderr (for CVE-2014-3672 check)"); + exit(-1); + } + if (!S_ISREG(stab.st_mode)) + return; + if (stab.st_size <= limit) + return; + + /* oh dear */ + fprintf(stderr,"\r\n" + "Closing stderr due to CVE-2014-3672 limit. " + " Set XEN_QEMU_CONSOLE_LIMIT to number of bytes to override," + " or 0 for no limit.\n"); + fflush(stderr); + + int nfd = open("/dev/null", O_WRONLY); + if (nfd < 0) { + perror("open /dev/null (for CVE-2014-3672 check)"); + exit(-1); + } + r = dup2(nfd, fd); + if (r != fd) { + perror("dup2 /dev/null (for CVE-2014-3672 check)"); + exit(-1); + } + close(nfd); +} + static int max_priority; #ifndef _WIN32 @@ -216,6 +260,8 @@ static int os_host_main_loop_wait(int64_t timeout) int ret; static int spin_counter; + check_cve_2014_3672_xen(); + glib_pollfds_fill(&timeout); /* If the I/O thread is very busy or we are incorrectly busy waiting in @@ -407,6 +453,8 @@ static int os_host_main_loop_wait(int64_t timeout) fd_set rfds, wfds, xfds; int nfds; + check_cve_2014_3672_xen(); + /* XXX: need to suppress polling by better using win32 events */ ret = 0; for (pe = first_polling_entry; pe != NULL; pe = pe->next) { -- 1.7.10.4