Blame SOURCES/0049-Fix-some-integer-overflow-causing-large-memory-alloc.patch

e2c81d
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
73b8f2
From: Frediano Ziglio <fziglio@redhat.com>
73b8f2
Date: Thu, 17 Sep 2015 15:00:22 +0100
e2c81d
Subject: [PATCH] Fix some integer overflow causing large memory allocations
73b8f2
73b8f2
Prevent integer overflow when computing image sizes.
73b8f2
Image index computations are done using 32 bit so this can cause easily
73b8f2
security issues. MAX_DATA_CHUNK is larger than the virtual
73b8f2
card limit, so this is not going to cause change in behaviours.
73b8f2
Comparing size calculation results with MAX_DATA_CHUNK will allow us to
73b8f2
catch overflows.
73b8f2
Prevent guest from allocating large amount of memory.
73b8f2
73b8f2
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
73b8f2
---
73b8f2
 server/red_parse_qxl.c | 15 +++++++++++----
73b8f2
 1 file changed, 11 insertions(+), 4 deletions(-)
73b8f2
73b8f2
diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
73b8f2
index 4449f2c..ceb2759 100644
73b8f2
--- a/server/red_parse_qxl.c
73b8f2
+++ b/server/red_parse_qxl.c
73b8f2
@@ -384,7 +384,7 @@ static SpiceImage *red_get_image(RedMemSlotInfo *slots, int group_id,
73b8f2
     QXLImage *qxl;
73b8f2
     SpiceImage *red = NULL;
73b8f2
     SpicePalette *rp = NULL;
73b8f2
-    size_t bitmap_size, size;
73b8f2
+    uint64_t bitmap_size, size;
73b8f2
     uint8_t qxl_flags;
73b8f2
     int error;
73b8f2
 
73b8f2
@@ -460,7 +460,10 @@ static SpiceImage *red_get_image(RedMemSlotInfo *slots, int group_id,
73b8f2
             red->u.bitmap.palette = rp;
73b8f2
             red->u.bitmap.palette_id = rp->unique;
73b8f2
         }
73b8f2
-        bitmap_size = red->u.bitmap.y * abs(red->u.bitmap.stride);
73b8f2
+        bitmap_size = (uint64_t) red->u.bitmap.y * red->u.bitmap.stride;
73b8f2
+        if (bitmap_size > MAX_DATA_CHUNK) {
73b8f2
+            goto error;
73b8f2
+        }
73b8f2
         if (qxl_flags & QXL_BITMAP_DIRECT) {
73b8f2
             red->u.bitmap.data = red_get_image_data_flat(slots, group_id,
73b8f2
                                                          qxl->bitmap.data,
73b8f2
@@ -1220,7 +1223,7 @@ int red_get_surface_cmd(RedMemSlotInfo *slots, int group_id,
73b8f2
                         RedSurfaceCmd *red, QXLPHYSICAL addr)
73b8f2
 {
73b8f2
     QXLSurfaceCmd *qxl;
73b8f2
-    size_t size;
73b8f2
+    uint64_t size;
73b8f2
     int error;
73b8f2
 
73b8f2
     qxl = (QXLSurfaceCmd *)get_virt(slots, addr, sizeof(*qxl), group_id,
73b8f2
@@ -1240,7 +1243,11 @@ 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
-        size = red->u.surface_create.height * abs(red->u.surface_create.stride);
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
+            return 1;
73b8f2
+        }
73b8f2
         red->u.surface_create.data =
73b8f2
             (uint8_t*)get_virt(slots, qxl->u.surface_create.data, size, group_id, &error);
73b8f2
         if (error) {