[Spice-devel] [PATCH spice-server v3] red-parse-qxl: Fix QUIC images from QXL

Uri Lublin uril at redhat.com
Wed Jul 31 15:24:44 UTC 2019


On 7/31/19 6:13 PM, Frediano Ziglio wrote:
> The decoding is wrong, the Red and QXL structures are different so
> code is not doing what is expected. red-parse-qxl translate from QXL
> to Red structures, red-record-qxl saves Red structure to file,
> red-replay-qxl is supposed to read from file into QXL directly.
> 
> If a Quic image is stored inside QXL memory the layout of the QXLImage
> in memory is:
> - QXLImageDescriptor
> - QXLQUICData
> - QXLDataChunk
> - first chunk data
> and all remaining data in linked QXLDataChunk.
> red_replay_image was reading the image as data was all contained in
> QXLImage->quic.data however "data" should store the first QXLDataChunk
> followed by QXLDataChunk data.
> Use proper base_size calling red_replay_data_chunks in order to
> initialise the image with the first data chunk correctly.
> 
> Not easy to reproduce, the only driver is XDDM which means Windows XP
> or similars. To enable QUIC encoding I added "image-compression=quic"
> and "streaming-video=off" to "-spice" Qemu option in order to force
> QUIC encoding in the guest driver (thanks to Uri Lublin for the help
> reproducing it).
> 
> Signed-off-by: Frediano Ziglio <fziglio at redhat.com>

Ack.

Uri.

> ---
>   server/red-replay-qxl.c | 17 ++++++++++++-----
>   1 file changed, 12 insertions(+), 5 deletions(-)
> 
> Changes from v2:
> - back to v1 with reproduction and explanation.
> 
> diff --git a/server/red-replay-qxl.c b/server/red-replay-qxl.c
> index 674feae2f..7104c81cd 100644
> --- a/server/red-replay-qxl.c
> +++ b/server/red-replay-qxl.c
> @@ -416,7 +416,7 @@ static uint8_t *red_replay_image_data_flat(SpiceReplay *replay, size_t *size)
>   
>   static QXLImage *red_replay_image(SpiceReplay *replay, uint32_t flags)
>   {
> -    QXLImage* qxl = NULL;
> +    QXLImage* qxl = NULL, *data;
>       size_t bitmap_size;
>       ssize_t size;
>       uint8_t qxl_flags;
> @@ -497,10 +497,15 @@ static QXLImage *red_replay_image(SpiceReplay *replay, uint32_t flags)
>           if (replay->error) {
>               return NULL;
>           }
> -        qxl = replay_realloc(replay, qxl, sizeof(QXLImageDescriptor) + sizeof(QXLQUICData) +
> -                             qxl->quic.data_size);
> -        size = red_replay_data_chunks(replay, "quic.data", (uint8_t**)&qxl->quic.data, 0);
> +        data = NULL;
> +        size = red_replay_data_chunks(replay, "quic.data", (uint8_t**)&data,
> +                                      sizeof(QXLImageDescriptor) + sizeof(QXLQUICData) +
> +                                      sizeof(QXLDataChunk));
>           spice_assert(size == qxl->quic.data_size);
> +        data->descriptor = qxl->descriptor;
> +        data->quic.data_size = qxl->quic.data_size;
> +        replay_free(replay, qxl);
> +        qxl = data;
>           break;
>       default:
>           spice_warn_if_reached();
> @@ -526,7 +531,9 @@ static void red_replay_image_free(SpiceReplay *replay, QXLPHYSICAL p, uint32_t f
>       case SPICE_IMAGE_TYPE_SURFACE:
>           break;
>       case SPICE_IMAGE_TYPE_QUIC:
> -        red_replay_data_chunks_free(replay, qxl, 0);
> +        red_replay_data_chunks_free(replay, qxl,
> +                                    sizeof(QXLImageDescriptor) + sizeof(QXLQUICData) +
> +                                    sizeof(QXLDataChunk));
>           qxl = NULL;
>           break;
>       default:
> 



More information about the Spice-devel mailing list