summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/qemu/qemu/hw-display-qxl-Pass-requested-buffer-size-to-qxl_phy.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/qemu/qemu/hw-display-qxl-Pass-requested-buffer-size-to-qxl_phy.patch')
-rw-r--r--meta/recipes-devtools/qemu/qemu/hw-display-qxl-Pass-requested-buffer-size-to-qxl_phy.patch236
1 files changed, 236 insertions, 0 deletions
diff --git a/meta/recipes-devtools/qemu/qemu/hw-display-qxl-Pass-requested-buffer-size-to-qxl_phy.patch b/meta/recipes-devtools/qemu/qemu/hw-display-qxl-Pass-requested-buffer-size-to-qxl_phy.patch
new file mode 100644
index 0000000000..f380be486c
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/hw-display-qxl-Pass-requested-buffer-size-to-qxl_phy.patch
@@ -0,0 +1,236 @@
1From 5a44a01c9eca6507be45d107c27377a3e8d0ee8c Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@linaro.org>
3Date: Mon, 28 Nov 2022 21:27:39 +0100
4Subject: [PATCH] hw/display/qxl: Pass requested buffer size to qxl_phys2virt()
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9Currently qxl_phys2virt() doesn't check for buffer overrun.
10In order to do so in the next commit, pass the buffer size
11as argument.
12
13For QXLCursor in qxl_render_cursor() -> qxl_cursor() we
14verify the size of the chunked data ahead, checking we can
15access 'sizeof(QXLCursor) + chunk->data_size' bytes.
16Since in the SPICE_CURSOR_TYPE_MONO case the cursor is
17assumed to fit in one chunk, no change are required.
18In SPICE_CURSOR_TYPE_ALPHA the ahead read is handled in
19qxl_unpack_chunks().
20
21Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
22Acked-by: Gerd Hoffmann <kraxel@redhat.com>
23Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
24Message-Id: <20221128202741.4945-4-philmd@linaro.org>
25
26Backport and rebase patch to fix compile error which imported by CVE-2022-4144.patch:
27
28/qxl.c: In function 'qxl_phys2virt':
29| /home/hitendra/work/yocto-work/cgx-data/dunfell-3.1/x86-generic-64-5.4-3.1-cgx/project/tmp/work/i586-montavistamllib32-linux/lib32-qemu/4.2.0-r0.8/qemu-4.2.0/hw/display/qxl.c:1508:67: error: 'size' undeclared (first use in this function); did you mean 'gsize'?
30| 1508 | if (!qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset, size)) {
31| | ^~~~
32| | gsize
33
34Upstream-Status: Backport [https://github.com/qemu/qemu/commit/61c34fc && https://gitlab.com/qemu-project/qemu/-/commit/8efec0ef8bbc1e75a7ebf6e325a35806ece9b39f]
35
36Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
37---
38 hw/display/qxl-logger.c | 22 +++++++++++++++++++---
39 hw/display/qxl-render.c | 20 ++++++++++++++++----
40 hw/display/qxl.c | 17 +++++++++++------
41 hw/display/qxl.h | 3 ++-
42 4 files changed, 48 insertions(+), 14 deletions(-)
43
44diff --git a/hw/display/qxl-logger.c b/hw/display/qxl-logger.c
45index 2ec6d8fa..031ddfec 100644
46--- a/hw/display/qxl-logger.c
47+++ b/hw/display/qxl-logger.c
48@@ -106,7 +106,7 @@ static int qxl_log_image(PCIQXLDevice *qxl, QXLPHYSICAL addr, int group_id)
49 QXLImage *image;
50 QXLImageDescriptor *desc;
51
52- image = qxl_phys2virt(qxl, addr, group_id);
53+ image = qxl_phys2virt(qxl, addr, group_id, sizeof(QXLImage));
54 if (!image) {
55 return 1;
56 }
57@@ -216,7 +216,8 @@ int qxl_log_cmd_cursor(PCIQXLDevice *qxl, QXLCursorCmd *cmd, int group_id)
58 cmd->u.set.position.y,
59 cmd->u.set.visible ? "yes" : "no",
60 cmd->u.set.shape);
61- cursor = qxl_phys2virt(qxl, cmd->u.set.shape, group_id);
62+ cursor = qxl_phys2virt(qxl, cmd->u.set.shape, group_id,
63+ sizeof(QXLCursor));
64 if (!cursor) {
65 return 1;
66 }
67@@ -238,6 +239,7 @@ int qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext)
68 {
69 bool compat = ext->flags & QXL_COMMAND_FLAG_COMPAT;
70 void *data;
71+ size_t datasz;
72 int ret;
73
74 if (!qxl->cmdlog) {
75@@ -249,7 +251,20 @@ int qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext)
76 qxl_name(qxl_type, ext->cmd.type),
77 compat ? "(compat)" : "");
78
79- data = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
80+ switch (ext->cmd.type) {
81+ case QXL_CMD_DRAW:
82+ datasz = compat ? sizeof(QXLCompatDrawable) : sizeof(QXLDrawable);
83+ break;
84+ case QXL_CMD_SURFACE:
85+ datasz = sizeof(QXLSurfaceCmd);
86+ break;
87+ case QXL_CMD_CURSOR:
88+ datasz = sizeof(QXLCursorCmd);
89+ break;
90+ default:
91+ goto out;
92+ }
93+ data = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id, datasz);
94 if (!data) {
95 return 1;
96 }
97@@ -271,6 +286,7 @@ int qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext)
98 qxl_log_cmd_cursor(qxl, data, ext->group_id);
99 break;
100 }
101+out:
102 fprintf(stderr, "\n");
103 return 0;
104 }
105diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c
106index d532e157..a65a6d64 100644
107--- a/hw/display/qxl-render.c
108+++ b/hw/display/qxl-render.c
109@@ -107,7 +107,9 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
110 qxl->guest_primary.resized = 0;
111 qxl->guest_primary.data = qxl_phys2virt(qxl,
112 qxl->guest_primary.surface.mem,
113- MEMSLOT_GROUP_GUEST);
114+ MEMSLOT_GROUP_GUEST,
115+ qxl->guest_primary.abs_stride
116+ * height);
117 if (!qxl->guest_primary.data) {
118 return;
119 }
120@@ -222,7 +224,8 @@ static void qxl_unpack_chunks(void *dest, size_t size, PCIQXLDevice *qxl,
121 if (offset == size) {
122 return;
123 }
124- chunk = qxl_phys2virt(qxl, chunk->next_chunk, group_id);
125+ chunk = qxl_phys2virt(qxl, chunk->next_chunk, group_id,
126+ sizeof(QXLDataChunk) + chunk->data_size);
127 if (!chunk) {
128 return;
129 }
130@@ -289,7 +292,8 @@ fail:
131 /* called from spice server thread context only */
132 int qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext)
133 {
134- QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
135+ QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id,
136+ sizeof(QXLCursorCmd));
137 QXLCursor *cursor;
138 QEMUCursor *c;
139
140@@ -308,7 +312,15 @@ int qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext)
141 }
142 switch (cmd->type) {
143 case QXL_CURSOR_SET:
144- cursor = qxl_phys2virt(qxl, cmd->u.set.shape, ext->group_id);
145+ /* First read the QXLCursor to get QXLDataChunk::data_size ... */
146+ cursor = qxl_phys2virt(qxl, cmd->u.set.shape, ext->group_id,
147+ sizeof(QXLCursor));
148+ if (!cursor) {
149+ return 1;
150+ }
151+ /* Then read including the chunked data following QXLCursor. */
152+ cursor = qxl_phys2virt(qxl, cmd->u.set.shape, ext->group_id,
153+ sizeof(QXLCursor) + cursor->chunk.data_size);
154 if (!cursor) {
155 return 1;
156 }
157diff --git a/hw/display/qxl.c b/hw/display/qxl.c
158index 6bc8385b..858d3e93 100644
159--- a/hw/display/qxl.c
160+++ b/hw/display/qxl.c
161@@ -275,7 +275,8 @@ static void qxl_spice_monitors_config_async(PCIQXLDevice *qxl, int replay)
162 QXL_IO_MONITORS_CONFIG_ASYNC));
163 }
164
165- cfg = qxl_phys2virt(qxl, qxl->guest_monitors_config, MEMSLOT_GROUP_GUEST);
166+ cfg = qxl_phys2virt(qxl, qxl->guest_monitors_config, MEMSLOT_GROUP_GUEST,
167+ sizeof(QXLMonitorsConfig));
168 if (cfg != NULL && cfg->count == 1) {
169 qxl->guest_primary.resized = 1;
170 qxl->guest_head0_width = cfg->heads[0].width;
171@@ -460,7 +461,8 @@ static int qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext)
172 switch (le32_to_cpu(ext->cmd.type)) {
173 case QXL_CMD_SURFACE:
174 {
175- QXLSurfaceCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
176+ QXLSurfaceCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id,
177+ sizeof(QXLSurfaceCmd));
178
179 if (!cmd) {
180 return 1;
181@@ -494,7 +496,8 @@ static int qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext)
182 }
183 case QXL_CMD_CURSOR:
184 {
185- QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
186+ QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id,
187+ sizeof(QXLCursorCmd));
188
189 if (!cmd) {
190 return 1;
191@@ -674,7 +677,8 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
192 *
193 * https://cgit.freedesktop.org/spice/win32/qxl-wddm-dod/commit/?id=f6e099db39e7d0787f294d5fd0dce328b5210faa
194 */
195- void *msg = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
196+ void *msg = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id,
197+ sizeof(QXLCommandRing));
198 if (msg != NULL && (
199 msg < (void *)qxl->vga.vram_ptr ||
200 msg > ((void *)qxl->vga.vram_ptr + qxl->vga.vram_size))) {
201@@ -1494,7 +1498,8 @@ static bool qxl_get_check_slot_offset(PCIQXLDevice *qxl, QXLPHYSICAL pqxl,
202 }
203
204 /* can be also called from spice server thread context */
205-void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
206+void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id,
207+ size_t size)
208 {
209 uint64_t offset;
210 uint32_t slot;
211@@ -1994,7 +1999,7 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
212 }
213
214 cmd = qxl_phys2virt(qxl, qxl->guest_surfaces.cmds[i],
215- MEMSLOT_GROUP_GUEST);
216+ MEMSLOT_GROUP_GUEST, sizeof(QXLSurfaceCmd));
217 assert(cmd);
218 assert(cmd->type == QXL_SURFACE_CMD_CREATE);
219 qxl_dirty_one_surface(qxl, cmd->u.surface_create.data,
220diff --git a/hw/display/qxl.h b/hw/display/qxl.h
221index 80eb0d26..fcfd133a 100644
222--- a/hw/display/qxl.h
223+++ b/hw/display/qxl.h
224@@ -147,7 +147,8 @@ typedef struct PCIQXLDevice {
225 #define QXL_DEFAULT_REVISION QXL_REVISION_STABLE_V12
226
227 /* qxl.c */
228-void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id);
229+void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id,
230+ size_t size);
231 void qxl_set_guest_bug(PCIQXLDevice *qxl, const char *msg, ...)
232 GCC_FMT_ATTR(2, 3);
233
234--
2352.25.1
236