Blame SOURCES/0067-create-a-function-to-validate-surface-parameters.patch

6e1750
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
6e1750
From: Frediano Ziglio <fziglio@redhat.com>
6e1750
Date: Mon, 29 Feb 2016 14:24:03 +0000
6e1750
Subject: [PATCH] create a function to validate surface parameters
6e1750
6e1750
Make possible to reuse it outside red-parse-qxl.c
6e1750
6e1750
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
6e1750
---
6e1750
 server/red_parse_qxl.c | 50 ++++++++++++++++++++++++++++++++------------------
6e1750
 server/red_parse_qxl.h |  5 +++++
6e1750
 2 files changed, 37 insertions(+), 18 deletions(-)
6e1750
6e1750
diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
6e1750
index bd0c408..7dc6a4d 100644
6e1750
--- a/server/red_parse_qxl.c
6e1750
+++ b/server/red_parse_qxl.c
6e1750
@@ -19,7 +19,6 @@
6e1750
 #include <config.h>
6e1750
 #endif
6e1750
 
6e1750
-#include <stdbool.h>
6e1750
 #include <inttypes.h>
6e1750
 #include <glib.h>
6e1750
 #include "common/lz_common.h"
6e1750
@@ -1306,13 +1305,41 @@ static unsigned int surface_format_to_bpp(uint32_t format)
6e1750
     return 0;
6e1750
 }
6e1750
 
6e1750
+bool red_validate_surface(uint32_t width, uint32_t height,
6e1750
+                          int32_t stride, uint32_t format)
6e1750
+{
6e1750
+    unsigned int bpp;
6e1750
+    uint64_t size;
6e1750
+
6e1750
+    bpp = surface_format_to_bpp(format);
6e1750
+
6e1750
+    /* check if format is valid */
6e1750
+    if (!bpp) {
6e1750
+        return false;
6e1750
+    }
6e1750
+
6e1750
+    /* check stride is larger than required bytes */
6e1750
+    size = ((uint64_t) width * bpp + 7u) / 8u;
6e1750
+    /* the uint32_t conversion is here to avoid problems with -2^31 value */
6e1750
+    if (stride == G_MININT32 || size > (uint32_t) abs(stride)) {
6e1750
+        return false;
6e1750
+    }
6e1750
+
6e1750
+    /* the multiplication can overflow, also abs(-2^31) may return a negative value */
6e1750
+    size = (uint64_t) height * abs(stride);
6e1750
+    if (size > MAX_DATA_CHUNK) {
6e1750
+        return false;
6e1750
+    }
6e1750
+
6e1750
+    return true;
6e1750
+}
6e1750
+
6e1750
 int red_get_surface_cmd(RedMemSlotInfo *slots, int group_id,
6e1750
                         RedSurfaceCmd *red, QXLPHYSICAL addr)
6e1750
 {
6e1750
     QXLSurfaceCmd *qxl;
6e1750
     uint64_t size;
6e1750
     int error;
6e1750
-    unsigned int bpp;
6e1750
 
6e1750
     qxl = (QXLSurfaceCmd *)get_virt(slots, addr, sizeof(*qxl), group_id,
6e1750
                                     &error);
6e1750
@@ -1331,26 +1358,13 @@ int red_get_surface_cmd(RedMemSlotInfo *slots, int group_id,
6e1750
         red->u.surface_create.width  = qxl->u.surface_create.width;
6e1750
         red->u.surface_create.height = qxl->u.surface_create.height;
6e1750
         red->u.surface_create.stride = qxl->u.surface_create.stride;
6e1750
-        bpp = surface_format_to_bpp(red->u.surface_create.format);
6e1750
 
6e1750
-        /* check if format is valid */
6e1750
-        if (!bpp) {
6e1750
+        if (!red_validate_surface(red->u.surface_create.width, red->u.surface_create.height,
6e1750
+                                  red->u.surface_create.stride, red->u.surface_create.format)) {
6e1750
             return 1;
6e1750
         }
6e1750
 
6e1750
-        /* check stride is larger than required bytes */
6e1750
-        size = ((uint64_t) red->u.surface_create.width * bpp + 7u) / 8u;
6e1750
-        /* the uint32_t conversion is here to avoid problems with -2^31 value */
6e1750
-        if (red->u.surface_create.stride == G_MININT32
6e1750
-            || size > (uint32_t) abs(red->u.surface_create.stride)) {
6e1750
-            return 1;
6e1750
-        }
6e1750
-
6e1750
-        /* the multiplication can overflow, also abs(-2^31) may return a negative value */
6e1750
-        size = (uint64_t) red->u.surface_create.height * abs(red->u.surface_create.stride);
6e1750
-        if (size > MAX_DATA_CHUNK) {
6e1750
-            return 1;
6e1750
-        }
6e1750
+        size = red->u.surface_create.height * abs(red->u.surface_create.stride);
6e1750
         red->u.surface_create.data =
6e1750
             (uint8_t*)get_virt(slots, qxl->u.surface_create.data, size, group_id, &error);
6e1750
         if (error) {
6e1750
diff --git a/server/red_parse_qxl.h b/server/red_parse_qxl.h
6e1750
index 3adc9fa..e18d8d0 100644
6e1750
--- a/server/red_parse_qxl.h
6e1750
+++ b/server/red_parse_qxl.h
6e1750
@@ -19,6 +19,8 @@
6e1750
 #ifndef RED_ABI_TRANSLATE_H
6e1750
 #define RED_ABI_TRANSLATE_H
6e1750
 
6e1750
+#include <stdbool.h>
6e1750
+
6e1750
 #include <spice/qxl_dev.h>
6e1750
 #include "red_common.h"
6e1750
 #include "red_memslots.h"
6e1750
@@ -128,6 +130,9 @@ int red_get_message(RedMemSlotInfo *slots, int group_id,
6e1750
                     RedMessage *red, QXLPHYSICAL addr);
6e1750
 void red_put_message(RedMessage *red);
6e1750
 
6e1750
+bool red_validate_surface(uint32_t width, uint32_t height,
6e1750
+                          int32_t stride, uint32_t format);
6e1750
+
6e1750
 int red_get_surface_cmd(RedMemSlotInfo *slots, int group_id,
6e1750
                         RedSurfaceCmd *red, QXLPHYSICAL addr);
6e1750
 void red_put_surface_cmd(RedSurfaceCmd *red);