958e1b
From 27d5bab00da6a59c9eae2e5f66dc985f1a0b95ac Mon Sep 17 00:00:00 2001
91048c
From: Gerd Hoffmann <kraxel@redhat.com>
91048c
Date: Mon, 15 Sep 2014 13:08:23 +0200
958e1b
Subject: [PATCH 4/4] spice: make sure we don't overflow ssd->buf
91048c
91048c
Message-id: <1410786503-19794-5-git-send-email-kraxel@redhat.com>
91048c
Patchwork-id: 61136
91048c
O-Subject: [RHEL-7.1 qemu-kvm PATCH 4/4] spice: make sure we don't overflow ssd->buf
958e1b
Bugzilla: 1139118
91048c
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
91048c
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
91048c
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
91048c
91048c
Related spice-only bug.  We have a fixed 16 MB buffer here, being
91048c
presented to the spice-server as qxl video memory in case spice is
91048c
used with a non-qxl card.  It's also used with qxl in vga mode.
91048c
91048c
When using display resolutions requiring more than 16 MB of memory we
91048c
are going to overflow that buffer.  In theory the guest can write,
91048c
indirectly via spice-server.  The spice-server clears the memory after
91048c
setting a new video mode though, triggering a segfault in the overflow
91048c
case, so qemu crashes before the guest has a chance to do something
91048c
evil.
91048c
91048c
Fix that by switching to dynamic allocation for the buffer.
91048c
91048c
CVE-2014-3615
91048c
91048c
Cc: qemu-stable@nongnu.org
91048c
Cc: secalert@redhat.com
91048c
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
91048c
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
91048c
(cherry picked from commit ab9509cceabef28071e41bdfa073083859c949a7)
91048c
91048c
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
91048c
---
91048c
 ui/spice-display.c |   20 +++++++++++++++-----
91048c
 1 files changed, 15 insertions(+), 5 deletions(-)
91048c
91048c
diff --git a/ui/spice-display.c b/ui/spice-display.c
958e1b
index 5d0a21e..dc8be8a 100644
91048c
--- a/ui/spice-display.c
91048c
+++ b/ui/spice-display.c
958e1b
@@ -291,11 +291,23 @@ void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd)
91048c
 void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
91048c
 {
91048c
     QXLDevSurfaceCreate surface;
91048c
+    uint64_t surface_size;
91048c
 
91048c
     memset(&surface, 0, sizeof(surface));
91048c
 
91048c
-    dprint(1, "%s/%d: %dx%d\n", __func__, ssd->qxl.id,
91048c
-           surface_width(ssd->ds), surface_height(ssd->ds));
91048c
+    surface_size = (uint64_t) surface_width(ssd->ds) *
91048c
+        surface_height(ssd->ds) * 4;
91048c
+    assert(surface_size > 0);
91048c
+    assert(surface_size < INT_MAX);
91048c
+    if (ssd->bufsize < surface_size) {
91048c
+        ssd->bufsize = surface_size;
91048c
+        g_free(ssd->buf);
91048c
+        ssd->buf = g_malloc(ssd->bufsize);
91048c
+    }
91048c
+
91048c
+    dprint(1, "%s/%d: %ux%u (size %" PRIu64 "/%d)\n", __func__, ssd->qxl.id,
91048c
+           surface_width(ssd->ds), surface_height(ssd->ds),
91048c
+           surface_size, ssd->bufsize);
91048c
 
91048c
     surface.format     = SPICE_SURFACE_FMT_32_xRGB;
91048c
     surface.width      = surface_width(ssd->ds);
958e1b
@@ -326,8 +338,6 @@ void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd)
91048c
     if (ssd->num_surfaces == 0) {
91048c
         ssd->num_surfaces = 1024;
91048c
     }
91048c
-    ssd->bufsize = (16 * 1024 * 1024);
91048c
-    ssd->buf = g_malloc(ssd->bufsize);
91048c
 }
91048c
 
91048c
 /* display listener callbacks */
958e1b
@@ -446,7 +456,7 @@ static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
91048c
     info->num_memslots = NUM_MEMSLOTS;
91048c
     info->num_memslots_groups = NUM_MEMSLOTS_GROUPS;
91048c
     info->internal_groupslot_id = 0;
91048c
-    info->qxl_ram_size = ssd->bufsize;
91048c
+    info->qxl_ram_size = 16 * 1024 * 1024;
91048c
     info->n_surfaces = ssd->num_surfaces;
91048c
 }
91048c
 
91048c
-- 
91048c
1.7.1
91048c