Blame SOURCES/0034-Validate-surface-bounding-box-before-using-it.patch

fce154
From 0d7971739587df80c82efaf3cc7932875b5e8c43 Mon Sep 17 00:00:00 2001
fce154
From: Christophe Fergeau <cfergeau@redhat.com>
fce154
Date: Tue, 9 Sep 2014 18:00:30 +0200
fce154
Subject: [PATCH] Validate surface bounding box before using it
fce154
fce154
It's possible for a buggy guest driver to pass invalid bounding box
fce154
dimensions in QXL commands, which would then cause spice-server to
fce154
segfault. This patch checks the size of the bounding box of the QXL
fce154
command right after it has been parsed.
fce154
fce154
This fixes rhbz#1135372
fce154
fce154
(cherry picked from commit e270edcbfd958d764e84cdbca6d403ff24fef610)
fce154
---
fce154
 server/red_worker.c | 31 +++++++++++++++++++++++++++++++
fce154
 1 file changed, 31 insertions(+)
fce154
fce154
diff --git a/server/red_worker.c b/server/red_worker.c
fce154
index 945f4f1..9e6a6ad 100644
fce154
--- a/server/red_worker.c
fce154
+++ b/server/red_worker.c
fce154
@@ -1272,6 +1272,33 @@ static inline void __validate_surface(RedWorker *worker, uint32_t surface_id)
fce154
     spice_warn_if(surface_id >= worker->n_surfaces);
fce154
 }
fce154
 
fce154
+static int validate_drawable_bbox(RedWorker *worker, RedDrawable *drawable)
fce154
+{
fce154
+        DrawContext *context;
fce154
+        uint32_t surface_id = drawable->surface_id;
fce154
+
fce154
+        /* surface_id must be validated before calling into
fce154
+         * validate_drawable_bbox
fce154
+         */
fce154
+        __validate_surface(worker, surface_id);
fce154
+        context = &worker->surfaces[surface_id].context;
fce154
+
fce154
+        if (drawable->bbox.top < 0)
fce154
+                return FALSE;
fce154
+        if (drawable->bbox.left < 0)
fce154
+                return FALSE;
fce154
+        if (drawable->bbox.bottom < 0)
fce154
+                return FALSE;
fce154
+        if (drawable->bbox.right < 0)
fce154
+                return FALSE;
fce154
+        if (drawable->bbox.bottom > context->height)
fce154
+                return FALSE;
fce154
+        if (drawable->bbox.right > context->width)
fce154
+                return FALSE;
fce154
+
fce154
+        return TRUE;
fce154
+}
fce154
+
fce154
 static inline int validate_surface(RedWorker *worker, uint32_t surface_id)
fce154
 {
fce154
     spice_warn_if(surface_id >= worker->n_surfaces);
fce154
@@ -4117,6 +4144,10 @@ static Drawable *get_drawable(RedWorker *worker, uint8_t effect, RedDrawable *re
fce154
             VALIDATE_SURFACE_RETVAL(worker, drawable->surfaces_dest[x], NULL)
fce154
         }
fce154
     }
fce154
+    if (!validate_drawable_bbox(worker, red_drawable)) {
fce154
+        rendering_incorrect(__func__);
fce154
+        return NULL;
fce154
+    }
fce154
     ring_init(&drawable->pipes);
fce154
     ring_init(&drawable->glz_ring);
fce154