From 8efec0ef8bbc1e75a7ebf6e325a35806ece9b39f Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Mon, 28 Nov 2022 21:27:39 +0100 Subject: hw/display/qxl: Pass requested buffer size to qxl_phys2virt() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently qxl_phys2virt() doesn't check for buffer overrun. In order to do so in the next commit, pass the buffer size as argument. For QXLCursor in qxl_render_cursor() -> qxl_cursor() we verify the size of the chunked data ahead, checking we can access 'sizeof(QXLCursor) + chunk->data_size' bytes. Since in the SPICE_CURSOR_TYPE_MONO case the cursor is assumed to fit in one chunk, no change are required. In SPICE_CURSOR_TYPE_ALPHA the ahead read is handled in qxl_unpack_chunks(). Signed-off-by: Philippe Mathieu-Daudé Acked-by: Gerd Hoffmann Signed-off-by: Stefan Hajnoczi Message-Id: <20221128202741.4945-4-philmd@linaro.org> --- hw/display/qxl-render.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'hw/display/qxl-render.c') diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c index ca217004bf..fcfd40c3ac 100644 --- a/hw/display/qxl-render.c +++ b/hw/display/qxl-render.c @@ -107,7 +107,9 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl) qxl->guest_primary.resized = 0; qxl->guest_primary.data = qxl_phys2virt(qxl, qxl->guest_primary.surface.mem, - MEMSLOT_GROUP_GUEST); + MEMSLOT_GROUP_GUEST, + qxl->guest_primary.abs_stride + * height); if (!qxl->guest_primary.data) { goto end; } @@ -228,7 +230,8 @@ 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); + chunk = qxl_phys2virt(qxl, chunk->next_chunk, group_id, + sizeof(QXLDataChunk) + chunk->data_size); if (!chunk) { return; } @@ -295,7 +298,8 @@ fail: /* called from spice server thread context only */ int qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext) { - QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id); + QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id, + sizeof(QXLCursorCmd)); QXLCursor *cursor; QEMUCursor *c; @@ -314,7 +318,15 @@ int qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext) } switch (cmd->type) { case QXL_CURSOR_SET: - cursor = qxl_phys2virt(qxl, cmd->u.set.shape, ext->group_id); + /* First read the QXLCursor to get QXLDataChunk::data_size ... */ + cursor = qxl_phys2virt(qxl, cmd->u.set.shape, ext->group_id, + sizeof(QXLCursor)); + if (!cursor) { + return 1; + } + /* Then read including the chunked data following QXLCursor. */ + cursor = qxl_phys2virt(qxl, cmd->u.set.shape, ext->group_id, + sizeof(QXLCursor) + cursor->chunk.data_size); if (!cursor) { return 1; } -- cgit 1.4.1