Hello community,

here is the log from the commit of package spice for openSUSE:Factory checked 
in at 2015-09-19 06:52:57
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/spice (Old)
 and      /work/SRC/openSUSE:Factory/.spice.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "spice"

Changes:
--------
--- /work/SRC/openSUSE:Factory/spice/spice.changes      2015-06-06 
09:53:35.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.spice.new/spice.changes 2015-09-19 
06:52:59.000000000 +0200
@@ -1,0 +2,6 @@
+Mon Sep  7 14:50:25 UTC 2015 - cbosdon...@suse.com
+
+- bsc#944460: fix CVE-2015-3247.
+  cve-2015-3247.patch 
+
+-------------------------------------------------------------------

New:
----
  cve-2015-3247.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ spice.spec ++++++
--- /var/tmp/diff_new_pack.0b8EQP/_old  2015-09-19 06:53:00.000000000 +0200
+++ /var/tmp/diff_new_pack.0b8EQP/_new  2015-09-19 06:53:00.000000000 +0200
@@ -29,6 +29,8 @@
 Patch0:         spice-Don-t-use-48kHz-for-playback-recording-rates.patch
 # PATCH-FIX-UPSTREAM password-length-check.patch boo#931044 
cbosdon...@suse.com -- Don't allow too long passwords
 Patch1:         password-length-check.patch
+# PATCH-FIX-UPSTREAM cve-2015-3247.patch cbosdon...@suse.com -- fix 
cve-2015-3247
+Patch2:         cve-2015-3247.patch 
 # Build-time parameters
 BuildRequires:  alsa-devel
 BuildRequires:  celt051-devel
@@ -90,6 +92,7 @@
 %setup -q
 %patch0 -p1
 %patch1 -p1
+%patch2 -p1
 
 %build
 %configure \

++++++ cve-2015-3247.patch ++++++
>From 524eef10c6c6c2f3f30be28c56b8f96adc7901f0 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fzig...@redhat.com>
Date: Tue, 9 Jun 2015 08:50:46 +0100
Subject: [PATCH] Avoid race conditions reading monitor configs from guest

For security reasons do not assume guest do not change structures it
pass to Qemu.
Guest could change count field while Qemu is copying QXLMonitorsConfig
structure leading to heap corruption.
This patch avoid it reading count only once.

Signed-off-by: Frediano Ziglio <fzig...@redhat.com>
---
 server/red_worker.c | 46 ++++++++++++++++++++++++++++++++--------------
 1 file changed, 32 insertions(+), 14 deletions(-)

diff --git a/server/red_worker.c b/server/red_worker.c
index 9e6a6ad..955cac2 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -11270,7 +11270,8 @@ static inline void 
red_monitors_config_item_add(DisplayChannelClient *dcc)
 }
 
 static void worker_update_monitors_config(RedWorker *worker,
-                                          QXLMonitorsConfig 
*dev_monitors_config)
+                                          QXLMonitorsConfig 
*dev_monitors_config,
+                                          uint16_t count, uint16_t max_allowed)
 {
     int heads_size;
     MonitorsConfig *monitors_config;
@@ -11279,22 +11280,22 @@ static void worker_update_monitors_config(RedWorker 
*worker,
     monitors_config_decref(worker->monitors_config);
 
     spice_debug("monitors config %d(%d)",
-                dev_monitors_config->count,
-                dev_monitors_config->max_allowed);
-    for (i = 0; i < dev_monitors_config->count; i++) {
+                count,
+                max_allowed);
+    for (i = 0; i < count; i++) {
         spice_debug("+%d+%d %dx%d",
                     dev_monitors_config->heads[i].x,
                     dev_monitors_config->heads[i].y,
                     dev_monitors_config->heads[i].width,
                     dev_monitors_config->heads[i].height);
     }
-    heads_size = dev_monitors_config->count * sizeof(QXLHead);
+    heads_size = count * sizeof(QXLHead);
     worker->monitors_config = monitors_config =
         spice_malloc(sizeof(*monitors_config) + heads_size);
     monitors_config->refs = 1;
     monitors_config->worker = worker;
-    monitors_config->count = dev_monitors_config->count;
-    monitors_config->max_allowed = dev_monitors_config->max_allowed;
+    monitors_config->count = count;
+    monitors_config->max_allowed = max_allowed;
     memcpy(monitors_config->heads, dev_monitors_config->heads, heads_size);
 }
 
@@ -11678,33 +11679,50 @@ void handle_dev_display_migrate(void *opaque, void 
*payload)
     red_migrate_display(worker, rcc);
 }
 
+static inline uint32_t qxl_monitors_config_size(uint32_t heads)
+{
+    return sizeof(QXLMonitorsConfig) + sizeof(QXLHead) * heads;
+}
+
 static void handle_dev_monitors_config_async(void *opaque, void *payload)
 {
     RedWorkerMessageMonitorsConfigAsync *msg = payload;
     RedWorker *worker = opaque;
-    int min_size = sizeof(QXLMonitorsConfig) + sizeof(QXLHead);
     int error;
+    uint16_t count, max_allowed;
     QXLMonitorsConfig *dev_monitors_config =
         (QXLMonitorsConfig*)get_virt(&worker->mem_slots, msg->monitors_config,
-                                     min_size, msg->group_id, &error);
+                                     qxl_monitors_config_size(1),
+                                     msg->group_id, &error);
 
     if (error) {
         /* TODO: raise guest bug (requires added QXL interface) */
         return;
     }
     worker->driver_cap_monitors_config = 1;
-    if (dev_monitors_config->count == 0) {
+    count = dev_monitors_config->count;
+    max_allowed = dev_monitors_config->max_allowed;
+    if (count == 0) {
         spice_warning("ignoring an empty monitors config message from driver");
         return;
     }
-    if (dev_monitors_config->count > dev_monitors_config->max_allowed) {
+    if (count > max_allowed) {
         spice_warning("ignoring malformed monitors_config from driver, "
                       "count > max_allowed %d > %d",
-                      dev_monitors_config->count,
-                      dev_monitors_config->max_allowed);
+                      count,
+                      max_allowed);
         return;
     }
-    worker_update_monitors_config(worker, dev_monitors_config);
+    /* get pointer again to check virtual size */
+    dev_monitors_config =
+        (QXLMonitorsConfig*)get_virt(&worker->mem_slots, msg->monitors_config,
+                                     qxl_monitors_config_size(count),
+                                     msg->group_id, &error);
+    if (error) {
+        /* TODO: raise guest bug (requires added QXL interface) */
+        return;
+    }
+    worker_update_monitors_config(worker, dev_monitors_config, count, 
max_allowed);
     red_worker_push_monitors_config(worker);
 }
 

Reply via email to