51 lines
1.9 KiB
Diff
51 lines
1.9 KiB
Diff
From: Michael Tokarev <mjt@tls.msk.ru>
|
|
Date: Fri, 21 Feb 2025 16:34:52 +0300
|
|
Subject: hw/display/qxl-render.c: fix qxl_unpack_chunks() chunk size calculation
|
|
Forwarded: https://lore.kernel.org/qemu-devel/20250221134856.478806-1-mjt@tls.msk.ru/T/#u
|
|
Bug: https://gitlab.com/qemu-project/qemu/-/issues/1628
|
|
|
|
In case of multiple chunks, code in qxl_unpack_chunks() takes size of the
|
|
wrong (next in the chain) chunk, instead of using current chunk size.
|
|
This leads to wrong number of bytes being copied, and to crashes if next
|
|
chunk size is larger than the current one.
|
|
|
|
Based on the code by Gao Yong.
|
|
|
|
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1628
|
|
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
|
|
---
|
|
hw/display/qxl-render.c | 11 ++++++++++-
|
|
1 file changed, 10 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c
|
|
index eda6d3de37..c6a9ac1da1 100644
|
|
--- a/hw/display/qxl-render.c
|
|
+++ b/hw/display/qxl-render.c
|
|
@@ -222,6 +222,7 @@ static void qxl_unpack_chunks(void *dest, size_t size, PCIQXLDevice *qxl,
|
|
uint32_t max_chunks = 32;
|
|
size_t offset = 0;
|
|
size_t bytes;
|
|
+ QXLPHYSICAL next_chunk_phys = 0;
|
|
|
|
for (;;) {
|
|
bytes = MIN(size - offset, chunk->data_size);
|
|
@@ -230,7 +231,15 @@ static void qxl_unpack_chunks(void *dest, size_t size, PCIQXLDevice *qxl,
|
|
if (offset == size) {
|
|
return;
|
|
}
|
|
- chunk = qxl_phys2virt(qxl, chunk->next_chunk, group_id,
|
|
+ next_chunk_phys = chunk->next_chunk;
|
|
+ /* fist time, only get the next chunk's data size */
|
|
+ chunk = qxl_phys2virt(qxl, next_chunk_phys, group_id,
|
|
+ sizeof(QXLDataChunk));
|
|
+ if (!chunk) {
|
|
+ return;
|
|
+ }
|
|
+ /* second time, check data size and get data */
|
|
+ chunk = qxl_phys2virt(qxl, next_chunk_phys, group_id,
|
|
sizeof(QXLDataChunk) + chunk->data_size);
|
|
if (!chunk) {
|
|
return;
|
|
--
|
|
2.39.5
|
|
|