hw/display/qxl: Pass requested buffer size to qxl_phys2virt()
References: bsc#1205808
Git-commit: 8efec0ef8b
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>
Signed-off-by: Dario Faggioli <dfaggioli@suse.com>
			
			
This commit is contained in:
		@@ -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;
 | 
			
		||||
@@ -1444,7 +1447,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;
 | 
			
		||||
@@ -1952,7 +1956,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,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user