xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* Xen Security Advisory 197 (CVE-2016-9381) - qemu incautious about shared ring processing
@ 2016-11-22 12:02 Xen.org security team
  0 siblings, 0 replies; only message in thread
From: Xen.org security team @ 2016-11-22 12:02 UTC (permalink / raw)
  To: xen-announce, xen-devel, xen-users, oss-security; +Cc: Xen.org security team

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

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

            Xen Security Advisory CVE-2016-9381 / XSA-197
                              version 3

             qemu incautious about shared ring processing

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

Added email header syntax to patches, for e.g. git-am.

Public release.

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

The compiler can emit optimizations in qemu which can lead to double
fetch vulnerabilities.  Specifically data on the rings shared between
qemu and the hypervisor (which the guest under control can obtain
mappings of) can be fetched twice (during which time the guest can
alter the contents) possibly leading to arbitrary code execution in
qemu.

IMPACT
======

Malicious administrators can exploit this vulnerability to take over
the qemu process, elevating its privilege to that of the qemu process.

In a system not using a device model stub domain (or other techniques
for deprivileging qemu), malicious guest administrators can thus
elevate their privilege to that of the host.

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

All Xen versions with all flavors of qemu are affected.

Only x86 HVM guests expose the vulnerability.  x86 PV guests do not
expose the vulnerability.

ARM systems are not vulnerable.

MITIGATION
==========

Running only PV guests will avoid the vulnerability.

Enabling stubdomains will mitigate this issue, by reducing the
escalation to only those privileges accorded to the service domain.
In a usual configuration, a service domain has only the privilege of
the guest, so this eliminates 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 yanghongke of Huawei Security Test Team.

RESOLUTION
==========

Applying the appropriate attached patch resolves this issue.

xsa197-qemuu.patch         qemu-upstream    xen-unstable, Xen 4.7.x
xsa197-qemut.patch         qemu-traditional xen-unstable, Xen 4.7.x, Xen 4.6.x
xsa197-4.6-qemuu.patch     qemu-upstream    Xen 4.6.x
xsa197-4.5-qemuu.patch     qemu-upstream    Xen 4.5.x
xsa197-4.5-qemut.patch     qemu-traditional Xen 4.5.x, Xen 4.4.x
xsa197-4.4-qemuu.patch     qemu-upstream    Xen 4.4.x

$ sha256sum xsa197*
a7d63958e3d3afc21c0585ec4690886a3191f01127583b4a29766c45fe4dd611  xsa197-4.4-qemuu.patch
56d037b3eaa0c3f5a7c474ad5087d8a41c2769d0d8b39c8f64699215a33e17a6  xsa197-4.5-qemut.patch
902836f0e5c6c46193c06f7c133a3bdd59f902ee490b962857640a6cd73e4be7  xsa197-4.5-qemuu.patch
20a418606f5536ac4fb009f21548a28b1b32dfb08fc97a259c40240d37a2abe8  xsa197-4.6-qemuu.patch
266996b2b5ac65ded76af63b3d57d4972ab95522b517e7bc9c5ff554d8c2d5e0  xsa197-qemut.patch
cd08b149c97b3f94dcda14b1f280dbb92911d93ffcd5dbcf5ee5ab2bebdc7878  xsa197-qemuu.patch
$

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

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

HOWEVER deployment of the stubdomain mitigation 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 in that case the configuration change may be visible
to the guest 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

iQEcBAEBAgAGBQJYNDNLAAoJEIP+FMlX6CvZTvUIALi45XVEJv4ZqNsB1kX3mXIF
5ocmSFCrSDDIcKEg2xQ49PKwqE/ZwMLhKuX0dFi/inidqx7FynYknziaR3svIeir
ALTDP6Emsk/OB7T4epjGnuFW05RTfkQmwzEyY/XCAJVrJlkzKGh3WYVtwk+/PELT
3ab9dMEcziaUM+Ax3phJ4PHi315If2rLS4gNfqGO5jv/gnMyXk4DHQ8QZUHIGs4F
8tA/ATPaZxNK8OIwGEIz32PlLxwWHsQQz6JEAtvNwGDTNMDwlx3RzHSvjJSLOIKB
Aap6qw4c9olK172LQbvBqvP09Eupi3YSevx3AD0gmqKVwj8ql/lNUSNBf9CSfPc=
=SBVo
-----END PGP SIGNATURE-----

[-- Attachment #2: xsa197-4.4-qemuu.patch --]
[-- Type: application/octet-stream, Size: 1853 bytes --]

From: Jan Beulich <jbeulich@suse.com>
Subject: xen: fix ioreq handling

Avoid double fetches and bounds check size to avoid overflowing
internal variables.

This is XSA-197.

Reported-by: yanghongke <yanghongke@huawei.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>

--- a/xen-all.c
+++ b/xen-all.c
@@ -705,6 +705,10 @@ static void cpu_ioreq_pio(ioreq_t *req)
 {
     uint32_t i;
 
+    if (req->size > sizeof(uint32_t)) {
+        hw_error("PIO: bad size (%u)", req->size);
+    }
+
     if (req->dir == IOREQ_READ) {
         if (!req->data_is_ptr) {
             req->data = do_inp(req->addr, req->size);
@@ -734,6 +738,10 @@ static void cpu_ioreq_move(ioreq_t *req)
 {
     uint32_t i;
 
+    if (req->size > sizeof(req->data)) {
+        hw_error("MMIO: bad size (%u)", req->size);
+    }
+
     if (!req->data_is_ptr) {
         if (req->dir == IOREQ_READ) {
             for (i = 0; i < req->count; i++) {
@@ -809,11 +817,13 @@ static int handle_buffered_iopage(XenIOS
         req.df = 1;
         req.type = buf_req->type;
         req.data_is_ptr = 0;
+        xen_rmb();
         qw = (req.size == 8);
         if (qw) {
             buf_req = &state->buffered_io_page->buf_ioreq[
                 (state->buffered_io_page->read_pointer + 1) % IOREQ_BUFFER_SLOT_NUM];
             req.data |= ((uint64_t)buf_req->data) << 32;
+            xen_rmb();
         }
 
         handle_ioreq(&req);
@@ -845,7 +855,11 @@ static void cpu_handle_ioreq(void *opaqu
 
     handle_buffered_iopage(state);
     if (req) {
-        handle_ioreq(req);
+        ioreq_t copy = *req;
+
+        xen_rmb();
+        handle_ioreq(&copy);
+        req->data = copy.data;
 
         if (req->state != STATE_IOREQ_INPROCESS) {
             fprintf(stderr, "Badness in I/O request ... not in service?!: "

[-- Attachment #3: xsa197-4.5-qemut.patch --]
[-- Type: application/octet-stream, Size: 1938 bytes --]

From: Jan Beulich <jbeulich@suse.com>
Subject: xen: fix ioreq handling

Avoid double fetches and bounds check size to avoid overflowing
internal variables.

This is XSA-197.

Reported-by: yanghongke <yanghongke@huawei.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Ian Jackson <ian.jackson@eu.citrix.com>

--- a/i386-dm/helper2.c
+++ b/i386-dm/helper2.c
@@ -374,6 +374,11 @@ static void cpu_ioreq_pio(CPUState *env,
 {
     uint32_t i;
 
+    if (req->size > sizeof(unsigned long)) {
+        fprintf(stderr, "PIO: bad size (%u)\n", req->size);
+        exit(-1);
+    }
+
     if (req->dir == IOREQ_READ) {
         if (!req->data_is_ptr) {
             req->data = do_inp(env, req->addr, req->size);
@@ -403,6 +408,11 @@ static void cpu_ioreq_move(CPUState *env
 {
     uint32_t i;
 
+    if (req->size > sizeof(req->data)) {
+        fprintf(stderr, "MMIO: bad size (%u)\n", req->size);
+        exit(-1);
+    }
+
     if (!req->data_is_ptr) {
         if (req->dir == IOREQ_READ) {
             for (i = 0; i < req->count; i++) {
@@ -506,11 +516,13 @@ static int __handle_buffered_iopage(CPUS
         req.df = 1;
         req.type = buf_req->type;
         req.data_is_ptr = 0;
+        xen_rmb();
         qw = (req.size == 8);
         if (qw) {
             buf_req = &buffered_io_page->buf_ioreq[
                 (buffered_io_page->read_pointer+1) % IOREQ_BUFFER_SLOT_NUM];
             req.data |= ((uint64_t)buf_req->data) << 32;
+            xen_rmb();
         }
 
         __handle_ioreq(env, &req);
@@ -543,7 +555,11 @@ static void cpu_handle_ioreq(void *opaqu
 
     __handle_buffered_iopage(env);
     if (req) {
-        __handle_ioreq(env, req);
+        ioreq_t copy = *req;
+
+        xen_rmb();
+        __handle_ioreq(env, &copy);
+        req->data = copy.data;
 
         if (req->state != STATE_IOREQ_INPROCESS) {
             fprintf(logfile, "Badness in I/O request ... not in service?!: "

[-- Attachment #4: xsa197-4.5-qemuu.patch --]
[-- Type: application/octet-stream, Size: 1853 bytes --]

From: Jan Beulich <jbeulich@suse.com>
Subject: xen: fix ioreq handling

Avoid double fetches and bounds check size to avoid overflowing
internal variables.

This is XSA-197.

Reported-by: yanghongke <yanghongke@huawei.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>

--- a/xen-hvm.c
+++ b/xen-hvm.c
@@ -722,6 +722,10 @@ static void cpu_ioreq_pio(ioreq_t *req)
 {
     uint32_t i;
 
+    if (req->size > sizeof(uint32_t)) {
+        hw_error("PIO: bad size (%u)", req->size);
+    }
+
     if (req->dir == IOREQ_READ) {
         if (!req->data_is_ptr) {
             req->data = do_inp(req->addr, req->size);
@@ -751,6 +755,10 @@ static void cpu_ioreq_move(ioreq_t *req)
 {
     uint32_t i;
 
+    if (req->size > sizeof(req->data)) {
+        hw_error("MMIO: bad size (%u)", req->size);
+    }
+
     if (!req->data_is_ptr) {
         if (req->dir == IOREQ_READ) {
             for (i = 0; i < req->count; i++) {
@@ -826,11 +834,13 @@ static int handle_buffered_iopage(XenIOS
         req.df = 1;
         req.type = buf_req->type;
         req.data_is_ptr = 0;
+        xen_rmb();
         qw = (req.size == 8);
         if (qw) {
             buf_req = &state->buffered_io_page->buf_ioreq[
                 (state->buffered_io_page->read_pointer + 1) % IOREQ_BUFFER_SLOT_NUM];
             req.data |= ((uint64_t)buf_req->data) << 32;
+            xen_rmb();
         }
 
         handle_ioreq(&req);
@@ -862,7 +872,11 @@ static void cpu_handle_ioreq(void *opaqu
 
     handle_buffered_iopage(state);
     if (req) {
-        handle_ioreq(req);
+        ioreq_t copy = *req;
+
+        xen_rmb();
+        handle_ioreq(&copy);
+        req->data = copy.data;
 
         if (req->state != STATE_IOREQ_INPROCESS) {
             fprintf(stderr, "Badness in I/O request ... not in service?!: "

[-- Attachment #5: xsa197-4.6-qemuu.patch --]
[-- Type: application/octet-stream, Size: 1856 bytes --]

From: Jan Beulich <jbeulich@suse.com>
Subject: xen: fix ioreq handling

Avoid double fetches and bounds check size to avoid overflowing
internal variables.

This is XSA-197.

Reported-by: yanghongke <yanghongke@huawei.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>

--- a/xen-hvm.c
+++ b/xen-hvm.c
@@ -817,6 +817,10 @@ static void cpu_ioreq_pio(ioreq_t *req)
 {
     uint32_t i;
 
+    if (req->size > sizeof(uint32_t)) {
+        hw_error("PIO: bad size (%u)", req->size);
+    }
+
     if (req->dir == IOREQ_READ) {
         if (!req->data_is_ptr) {
             req->data = do_inp(req->addr, req->size);
@@ -846,6 +850,10 @@ static void cpu_ioreq_move(ioreq_t *req)
 {
     uint32_t i;
 
+    if (req->size > sizeof(req->data)) {
+        hw_error("MMIO: bad size (%u)", req->size);
+    }
+
     if (!req->data_is_ptr) {
         if (req->dir == IOREQ_READ) {
             for (i = 0; i < req->count; i++) {
@@ -999,11 +1007,13 @@ static int handle_buffered_iopage(XenIOS
         req.df = 1;
         req.type = buf_req->type;
         req.data_is_ptr = 0;
+        xen_rmb();
         qw = (req.size == 8);
         if (qw) {
             buf_req = &buf_page->buf_ioreq[(rdptr + 1) %
                                            IOREQ_BUFFER_SLOT_NUM];
             req.data |= ((uint64_t)buf_req->data) << 32;
+            xen_rmb();
         }
 
         handle_ioreq(state, &req);
@@ -1034,7 +1044,11 @@ static void cpu_handle_ioreq(void *opaqu
 
     handle_buffered_iopage(state);
     if (req) {
-        handle_ioreq(state, req);
+        ioreq_t copy = *req;
+
+        xen_rmb();
+        handle_ioreq(state, &copy);
+        req->data = copy.data;
 
         if (req->state != STATE_IOREQ_INPROCESS) {
             fprintf(stderr, "Badness in I/O request ... not in service?!: "

[-- Attachment #6: xsa197-qemut.patch --]
[-- Type: application/octet-stream, Size: 1949 bytes --]

From: Jan Beulich <jbeulich@suse.com>
Subject: xen: fix ioreq handling

Avoid double fetches and bounds check size to avoid overflowing
internal variables.

This is XSA-197.

Reported-by: yanghongke <yanghongke@huawei.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Ian Jackson <ian.jackson@eu.citrix.com>

--- a/i386-dm/helper2.c
+++ b/i386-dm/helper2.c
@@ -375,6 +375,11 @@ static void cpu_ioreq_pio(CPUState *env,
 {
     uint32_t i;
 
+    if (req->size > sizeof(unsigned long)) {
+        fprintf(stderr, "PIO: bad size (%u)\n", req->size);
+        exit(-1);
+    }
+
     if (req->dir == IOREQ_READ) {
         if (!req->data_is_ptr) {
             req->data = do_inp(env, req->addr, req->size);
@@ -404,6 +409,11 @@ static void cpu_ioreq_move(CPUState *env
 {
     uint32_t i;
 
+    if (req->size > sizeof(req->data)) {
+        fprintf(stderr, "MMIO: bad size (%u)\n", req->size);
+        exit(-1);
+    }
+
     if (!req->data_is_ptr) {
         if (req->dir == IOREQ_READ) {
             for (i = 0; i < req->count; i++) {
@@ -516,11 +526,13 @@ static int __handle_buffered_iopage(CPUS
         req.df = 1;
         req.type = buf_req->type;
         req.data_is_ptr = 0;
+        xen_rmb();
         qw = (req.size == 8);
         if (qw) {
             buf_req = &buffered_io_page->buf_ioreq[(rdptr + 1) %
                                                    IOREQ_BUFFER_SLOT_NUM];
             req.data |= ((uint64_t)buf_req->data) << 32;
+            xen_rmb();
         }
 
         __handle_ioreq(env, &req);
@@ -552,7 +564,11 @@ static void cpu_handle_ioreq(void *opaqu
 
     __handle_buffered_iopage(env);
     if (req) {
-        __handle_ioreq(env, req);
+        ioreq_t copy = *req;
+
+        xen_rmb();
+        __handle_ioreq(env, &copy);
+        req->data = copy.data;
 
         if (req->state != STATE_IOREQ_INPROCESS) {
             fprintf(logfile, "Badness in I/O request ... not in service?!: "

[-- Attachment #7: xsa197-qemuu.patch --]
[-- Type: application/octet-stream, Size: 2096 bytes --]

From: Jan Beulich <jbeulich@suse.com>
Subject: xen: fix ioreq handling

Avoid double fetches and bounds check size to avoid overflowing
internal variables.

This is XSA-197.

Reported-by: yanghongke <yanghongke@huawei.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>

--- a/xen-hvm.c
+++ b/xen-hvm.c
@@ -810,6 +810,10 @@ static void cpu_ioreq_pio(ioreq_t *req)
     trace_cpu_ioreq_pio(req, req->dir, req->df, req->data_is_ptr, req->addr,
                          req->data, req->count, req->size);
 
+    if (req->size > sizeof(uint32_t)) {
+        hw_error("PIO: bad size (%u)", req->size);
+    }
+
     if (req->dir == IOREQ_READ) {
         if (!req->data_is_ptr) {
             req->data = do_inp(req->addr, req->size);
@@ -846,6 +850,10 @@ static void cpu_ioreq_move(ioreq_t *req)
     trace_cpu_ioreq_move(req, req->dir, req->df, req->data_is_ptr, req->addr,
                          req->data, req->count, req->size);
 
+    if (req->size > sizeof(req->data)) {
+        hw_error("MMIO: bad size (%u)", req->size);
+    }
+
     if (!req->data_is_ptr) {
         if (req->dir == IOREQ_READ) {
             for (i = 0; i < req->count; i++) {
@@ -1010,11 +1018,13 @@ static int handle_buffered_iopage(XenIOS
         req.df = 1;
         req.type = buf_req->type;
         req.data_is_ptr = 0;
+        xen_rmb();
         qw = (req.size == 8);
         if (qw) {
             buf_req = &buf_page->buf_ioreq[(rdptr + 1) %
                                            IOREQ_BUFFER_SLOT_NUM];
             req.data |= ((uint64_t)buf_req->data) << 32;
+            xen_rmb();
         }
 
         handle_ioreq(state, &req);
@@ -1045,7 +1055,11 @@ static void cpu_handle_ioreq(void *opaqu
 
     handle_buffered_iopage(state);
     if (req) {
-        handle_ioreq(state, req);
+        ioreq_t copy = *req;
+
+        xen_rmb();
+        handle_ioreq(state, &copy);
+        req->data = copy.data;
 
         if (req->state != STATE_IOREQ_INPROCESS) {
             fprintf(stderr, "Badness in I/O request ... not in service?!: "

[-- Attachment #8: Type: text/plain, Size: 127 bytes --]

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

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2016-11-22 12:02 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-11-22 12:02 Xen Security Advisory 197 (CVE-2016-9381) - qemu incautious about shared ring processing Xen.org security team

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).