Package: spice / 0.12.5-1+deb8u5

CVE-2015-5260_CVE-2015-5261/0005-Check-properly-surface-to-be-created.patch Patch series | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
From 1eb93baa3c594e1214b1c92bbad8a06e9c7e2d12 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Tue, 8 Sep 2015 16:02:59 +0100
Subject: [PATCH 05/19] Check properly surface to be created

Check format is valid.
Check stride is at least the size of required bytes for a row.

Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
---
 server/red_parse_qxl.c | 35 ++++++++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

--- a/server/red_parse_qxl.c
+++ b/server/red_parse_qxl.c
@@ -1220,12 +1220,30 @@ void red_put_message(RedMessage *red)
     /* nothing yet */
 }
 
+static unsigned int surface_format_to_bpp(uint32_t format)
+{
+    switch (format) {
+    case SPICE_SURFACE_FMT_1_A:
+        return 1;
+    case SPICE_SURFACE_FMT_8_A:
+        return 8;
+    case SPICE_SURFACE_FMT_16_555:
+    case SPICE_SURFACE_FMT_16_565:
+        return 16;
+    case SPICE_SURFACE_FMT_32_xRGB:
+    case SPICE_SURFACE_FMT_32_ARGB:
+        return 32;
+    }
+    return 0;
+}
+
 int red_get_surface_cmd(RedMemSlotInfo *slots, int group_id,
                         RedSurfaceCmd *red, QXLPHYSICAL addr)
 {
     QXLSurfaceCmd *qxl;
     uint64_t size;
     int error;
+    unsigned int bpp;
 
     qxl = (QXLSurfaceCmd *)get_virt(slots, addr, sizeof(*qxl), group_id,
                                     &error);
@@ -1244,9 +1262,24 @@ int red_get_surface_cmd(RedMemSlotInfo *
         red->u.surface_create.width  = qxl->u.surface_create.width;
         red->u.surface_create.height = qxl->u.surface_create.height;
         red->u.surface_create.stride = qxl->u.surface_create.stride;
+        bpp = surface_format_to_bpp(red->u.surface_create.format);
+
+        /* check if format is valid */
+        if (!bpp) {
+            return 1;
+        }
+
+        /* check stride is larger than required bytes */
+        size = ((uint64_t) red->u.surface_create.width * bpp + 7u) / 8u;
+        /* the uint32_t conversion is here to avoid problems with -2^31 value */
+        if (red->u.surface_create.stride == G_MININT32
+            || size > (uint32_t) abs(red->u.surface_create.stride)) {
+            return 1;
+        }
+
         /* the multiplication can overflow, also abs(-2^31) may return a negative value */
         size = (uint64_t) red->u.surface_create.height * abs(red->u.surface_create.stride);
-        if (size > MAX_DATA_CHUNK || red->u.surface_create.stride == G_MININT32) {
+        if (size > MAX_DATA_CHUNK) {
             return 1;
         }
         red->u.surface_create.data =