Blame SOURCES/0050-Check-properly-surface-to-be-created.patch

e2c81d
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
73b8f2
From: Frediano Ziglio <fziglio@redhat.com>
73b8f2
Date: Tue, 8 Sep 2015 16:02:59 +0100
e2c81d
Subject: [PATCH] Check properly surface to be created
73b8f2
73b8f2
Check format is valid.
73b8f2
Check stride is at least the size of required bytes for a row.
73b8f2
73b8f2
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
73b8f2
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
73b8f2
---
73b8f2
 server/red_parse_qxl.c | 35 ++++++++++++++++++++++++++++++++++-
73b8f2
 1 file changed, 34 insertions(+), 1 deletion(-)
73b8f2
73b8f2
diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
73b8f2
index ceb2759..a7ca71d 100644
73b8f2
--- a/server/red_parse_qxl.c
73b8f2
+++ b/server/red_parse_qxl.c
73b8f2
@@ -1219,12 +1219,30 @@ void red_put_message(RedMessage *red)
73b8f2
     /* nothing yet */
73b8f2
 }
73b8f2
 
73b8f2
+static unsigned int surface_format_to_bpp(uint32_t format)
73b8f2
+{
73b8f2
+    switch (format) {
73b8f2
+    case SPICE_SURFACE_FMT_1_A:
73b8f2
+        return 1;
73b8f2
+    case SPICE_SURFACE_FMT_8_A:
73b8f2
+        return 8;
73b8f2
+    case SPICE_SURFACE_FMT_16_555:
73b8f2
+    case SPICE_SURFACE_FMT_16_565:
73b8f2
+        return 16;
73b8f2
+    case SPICE_SURFACE_FMT_32_xRGB:
73b8f2
+    case SPICE_SURFACE_FMT_32_ARGB:
73b8f2
+        return 32;
73b8f2
+    }
73b8f2
+    return 0;
73b8f2
+}
73b8f2
+
73b8f2
 int red_get_surface_cmd(RedMemSlotInfo *slots, int group_id,
73b8f2
                         RedSurfaceCmd *red, QXLPHYSICAL addr)
73b8f2
 {
73b8f2
     QXLSurfaceCmd *qxl;
73b8f2
     uint64_t size;
73b8f2
     int error;
73b8f2
+    unsigned int bpp;
73b8f2
 
73b8f2
     qxl = (QXLSurfaceCmd *)get_virt(slots, addr, sizeof(*qxl), group_id,
73b8f2
                                     &error);
73b8f2
@@ -1243,9 +1261,24 @@ int red_get_surface_cmd(RedMemSlotInfo *slots, int group_id,
73b8f2
         red->u.surface_create.width  = qxl->u.surface_create.width;
73b8f2
         red->u.surface_create.height = qxl->u.surface_create.height;
73b8f2
         red->u.surface_create.stride = qxl->u.surface_create.stride;
73b8f2
+        bpp = surface_format_to_bpp(red->u.surface_create.format);
73b8f2
+
73b8f2
+        /* check if format is valid */
73b8f2
+        if (!bpp) {
73b8f2
+            return 1;
73b8f2
+        }
73b8f2
+
73b8f2
+        /* check stride is larger than required bytes */
73b8f2
+        size = ((uint64_t) red->u.surface_create.width * bpp + 7u) / 8u;
73b8f2
+        /* the uint32_t conversion is here to avoid problems with -2^31 value */
73b8f2
+        if (red->u.surface_create.stride == G_MININT32
73b8f2
+            || size > (uint32_t) abs(red->u.surface_create.stride)) {
73b8f2
+            return 1;
73b8f2
+        }
73b8f2
+
73b8f2
         /* the multiplication can overflow, also abs(-2^31) may return a negative value */
73b8f2
         size = (uint64_t) red->u.surface_create.height * abs(red->u.surface_create.stride);
73b8f2
-        if (size > MAX_DATA_CHUNK || red->u.surface_create.stride == G_MININT32) {
73b8f2
+        if (size > MAX_DATA_CHUNK) {
73b8f2
             return 1;
73b8f2
         }
73b8f2
         red->u.surface_create.data =