aboutsummaryrefslogtreecommitdiff
path: root/hw/display/qxl.c
diff options
context:
space:
mode:
authorPhilippe Mathieu-Daudé <philmd@linaro.org>2022-11-28 21:27:39 +0100
committerStefan Hajnoczi <stefanha@redhat.com>2022-11-29 18:15:26 -0500
commit8efec0ef8bbc1e75a7ebf6e325a35806ece9b39f (patch)
tree9c7f3b4dc9f8ea7aa7f207475d3aae1a25fe95f8 /hw/display/qxl.c
parentb1901de83a9456cde26fc755f71ca2b7b3ef50fc (diff)
downloadqemu-8efec0ef8bbc1e75a7ebf6e325a35806ece9b39f.zip
qemu-8efec0ef8bbc1e75a7ebf6e325a35806ece9b39f.tar.gz
qemu-8efec0ef8bbc1e75a7ebf6e325a35806ece9b39f.tar.bz2
hw/display/qxl: Pass requested buffer size to qxl_phys2virt()
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é <philmd@linaro.org> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Message-Id: <20221128202741.4945-4-philmd@linaro.org>
Diffstat (limited to 'hw/display/qxl.c')
-rw-r--r--hw/display/qxl.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index 5b10f69..231d733 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -274,7 +274,8 @@ static void qxl_spice_monitors_config_async(PCIQXLDevice *qxl, int replay)
QXL_IO_MONITORS_CONFIG_ASYNC));
}
- cfg = qxl_phys2virt(qxl, qxl->guest_monitors_config, MEMSLOT_GROUP_GUEST);
+ cfg = qxl_phys2virt(qxl, qxl->guest_monitors_config, MEMSLOT_GROUP_GUEST,
+ sizeof(QXLMonitorsConfig));
if (cfg != NULL && cfg->count == 1) {
qxl->guest_primary.resized = 1;
qxl->guest_head0_width = cfg->heads[0].width;
@@ -459,7 +460,8 @@ static int qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext)
switch (le32_to_cpu(ext->cmd.type)) {
case QXL_CMD_SURFACE:
{
- QXLSurfaceCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
+ QXLSurfaceCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id,
+ sizeof(QXLSurfaceCmd));
if (!cmd) {
return 1;
@@ -494,7 +496,8 @@ static int qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext)
}
case QXL_CMD_CURSOR:
{
- QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
+ QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id,
+ sizeof(QXLCursorCmd));
if (!cmd) {
return 1;
@@ -1456,7 +1459,8 @@ static bool qxl_get_check_slot_offset(PCIQXLDevice *qxl, QXLPHYSICAL pqxl,
}
/* can be also called from spice server thread context */
-void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
+void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id,
+ size_t size)
{
uint64_t offset;
uint32_t slot;
@@ -1964,7 +1968,7 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
}
cmd = qxl_phys2virt(qxl, qxl->guest_surfaces.cmds[i],
- MEMSLOT_GROUP_GUEST);
+ MEMSLOT_GROUP_GUEST, sizeof(QXLSurfaceCmd));
assert(cmd);
assert(cmd->type == QXL_SURFACE_CMD_CREATE);
qxl_dirty_one_surface(qxl, cmd->u.surface_create.data,