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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
From fc06265c3780e05503410a6646d1434e15d25b03 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Mon, 29 Feb 2016 14:24:03 +0000
Subject: [PATCH 1/2] factor out red_validate_surface function to validate
surface parameters
Make possible to reuse it outside red-parse-qxl.c.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
---
server/red-parse-qxl.c | 49 ++++++++++++++++++++++++++++++++-----------------
server/red-parse-qxl.h | 3 +++
2 files changed, 35 insertions(+), 17 deletions(-)
diff --git a/server/red-parse-qxl.c b/server/red-parse-qxl.c
index 18b7ea6..b462311 100644
--- a/server/red-parse-qxl.c
+++ b/server/red-parse-qxl.c
@@ -1327,13 +1327,41 @@ static unsigned int surface_format_to_bpp(uint32_t format)
return 0;
}
+bool red_validate_surface(uint32_t width, uint32_t height,
+ int32_t stride, uint32_t format)
+{
+ unsigned int bpp;
+ uint64_t size;
+
+ bpp = surface_format_to_bpp(format);
+
+ /* check if format is valid */
+ if (!bpp) {
+ return false;
+ }
+
+ /* check stride is larger than required bytes */
+ size = ((uint64_t) width * bpp + 7u) / 8u;
+ /* the uint32_t conversion is here to avoid problems with -2^31 value */
+ if (stride == G_MININT32 || size > (uint32_t) abs(stride)) {
+ return false;
+ }
+
+ /* the multiplication can overflow, also abs(-2^31) may return a negative value */
+ size = (uint64_t) height * abs(stride);
+ if (size > MAX_DATA_CHUNK) {
+ return false;
+ }
+
+ return true;
+}
+
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 *)memslot_get_virt(slots, addr, sizeof(*qxl), group_id,
&error);
@@ -1353,26 +1381,13 @@ int red_get_surface_cmd(RedMemSlotInfo *slots, int group_id,
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) {
+ if (!red_validate_surface(red->u.surface_create.width, red->u.surface_create.height,
+ red->u.surface_create.stride, red->u.surface_create.format)) {
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) {
- return 1;
- }
+ size = red->u.surface_create.height * abs(red->u.surface_create.stride);
red->u.surface_create.data =
(uint8_t*)memslot_get_virt(slots, qxl->u.surface_create.data, size, group_id, &error);
if (error) {
diff --git a/server/red-parse-qxl.h b/server/red-parse-qxl.h
index 9c30572..72a57b4 100644
--- a/server/red-parse-qxl.h
+++ b/server/red-parse-qxl.h
@@ -127,6 +127,9 @@ int red_get_message(RedMemSlotInfo *slots, int group_id,
RedMessage *red, QXLPHYSICAL addr);
void red_put_message(RedMessage *red);
+bool red_validate_surface(uint32_t width, uint32_t height,
+ int32_t stride, uint32_t format);
+
int red_get_surface_cmd(RedMemSlotInfo *slots, int group_id,
RedSurfaceCmd *red, QXLPHYSICAL addr);
void red_put_surface_cmd(RedSurfaceCmd *red);
--
2.7.3
|