[Spice-devel] [PATCH spice-common 1/2] canvas_base: Check for overflows decoding LZ4

Jonathon Jongsma jjongsma at redhat.com
Wed Jul 11 16:36:41 UTC 2018


On Tue, 2018-07-10 at 14:35 +0100, Frediano Ziglio wrote:
> Check we have enough data before reading.

Check *that* we have...

> This could lead to read buffer overflows being undetected.
> This is not a security issue, read happens only in the client not
> causing
> any information leakage, maximum can generate a crash or some garbage
> on
> the screen.
> 
> Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
> ---
>  common/canvas_base.c | 23 +++++++++++++++++++----
>  1 file changed, 19 insertions(+), 4 deletions(-)
> 
> diff --git a/common/canvas_base.c b/common/canvas_base.c
> index 05c4e1f..ae07625 100644
> --- a/common/canvas_base.c
> +++ b/common/canvas_base.c
> @@ -537,6 +537,9 @@ static pixman_image_t *canvas_get_lz4(CanvasBase
> *canvas, SpiceImage *image)
>      width = image->descriptor.width;
>      stride_encoded = width;
>      height = image->descriptor.height;
> +    if (data + 2 > data_end) {
> +        return NULL;

All other error conditions that you handle below print a warning. Do
you want one here as well?

Acked-by: Jonathon Jongsma <jjongsma at redhat.com>


> +    }
>      top_down = !!*(data++);
>      spice_format = *(data++);
>      switch (spice_format) {
> @@ -579,16 +582,22 @@ static pixman_image_t
> *canvas_get_lz4(CanvasBase *canvas, SpiceImage *image)
>      bits = dest;
>  
>      do {
> +        if (data + 4 > data_end) {
> +            goto format_error;
> +        }
>          // Read next compressed block
>          enc_size = read_uint32_be(data);
>          data += 4;
> +        /* check overflow. This check is a bit different to avoid
> +         * possible overflows. From previous check data_end - data
> cannot overflow.
> +         * Computing data + enc_size on 32 bit could cause
> overflows. */
> +        if (enc_size < 0 || data_end - data < (unsigned int)
> enc_size) {
> +            goto format_error;
> +        }
>          dec_size = LZ4_decompress_safe_continue(stream, (const char
> *) data,
>                                                  (char *) dest,
> enc_size, available);
>          if (dec_size <= 0) {
> -            spice_warning("Error decoding LZ4 block\n");
> -            pixman_image_unref(surface);
> -            surface = NULL;
> -            break;
> +            goto format_error;
>          }
>          dest += dec_size;
>          available -= dec_size;
> @@ -599,6 +608,12 @@ static pixman_image_t *canvas_get_lz4(CanvasBase
> *canvas, SpiceImage *image)
>  
>      LZ4_freeStreamDecode(stream);
>      return surface;
> +
> +format_error:
> +    spice_warning("Error decoding LZ4 block\n");
> +    LZ4_freeStreamDecode(stream);
> +    pixman_image_unref(surface);
> +    return NULL;
>  }
>  #endif
>  


More information about the Spice-devel mailing list