Sophie

Sophie

distrib > Mageia > 6 > armv7hl > media > core-updates-src > by-pkgid > 90556e2af02432e9e92dae99efa8c07d > files > 7

spice-gtk-0.33-3.1.mga6.src.rpm

From 7117d2dced9438ce8074d20362196a313b0854cc Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Mon, 25 Jun 2018 14:16:10 +0100
Subject: [PATCH spice-common 2/2] lz: More checks on image sizes

Extend sizes check also to decoding, actually the source data
decoding images should be less safe than encoding.
This avoids different integer overflows and buffer overflows.
To avoid potential issues images are limited to 1GB.

Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
---
 spice-common/common/lz.c | 36 +++++++++++++++++++++++++++---------
 1 file changed, 27 insertions(+), 9 deletions(-)

diff --git a/spice-common/spice-common/common/lz.c b/common/lz.c
index e76105e..f57d388 100644
--- a/spice-common/common/lz.c
+++ b/spice-common/common/lz.c
@@ -489,17 +489,13 @@ typedef uint16_t rgb16_pixel_t;
 #undef LZ_UNEXPECT_CONDITIONAL
 #undef LZ_EXPECT_CONDITIONAL
 
-int lz_encode(LzContext *lz, LzImageType type, int width, int height, int top_down,
-              uint8_t *lines, unsigned int num_lines, int stride,
-              uint8_t *io_ptr, unsigned int num_io_bytes)
+static void lz_check_sizes(Encoder *encoder)
 {
-    Encoder *encoder = (Encoder *)lz;
-    uint8_t *io_ptr_end = io_ptr + num_io_bytes;
+    const int width = encoder->width;
 
-    encoder->type = type;
-    encoder->width = width;
-    encoder->height = height;
-    encoder->stride = stride;
+    if (width < 0 || encoder->height < 0 || encoder->stride < 0) {
+        encoder->usr->error(encoder->usr, "invalid lz size\n");
+    }
 
     if (IS_IMAGE_TYPE_PLT[encoder->type]) {
         if (encoder->stride > (width / PLT_PIXELS_PER_BYTE[encoder->type])) {
@@ -516,6 +512,26 @@ int lz_encode(LzContext *lz, LzImageType type, int width, int height, int top_do
         }
     }
 
+    // avoid too big images, 1 GB is enough
+    if ((uint64_t) encoder->stride * encoder->height >= 1024u * 1024u * 1024u) {
+        encoder->usr->error(encoder->usr, "image too large\n");
+    }
+}
+
+int lz_encode(LzContext *lz, LzImageType type, int width, int height, int top_down,
+              uint8_t *lines, unsigned int num_lines, int stride,
+              uint8_t *io_ptr, unsigned int num_io_bytes)
+{
+    Encoder *encoder = (Encoder *)lz;
+    uint8_t *io_ptr_end = io_ptr + num_io_bytes;
+
+    encoder->type = type;
+    encoder->width = width;
+    encoder->height = height;
+    encoder->stride = stride;
+
+    lz_check_sizes(encoder);
+
     // assign the output buffer
     if (!encoder_reset(encoder, io_ptr, io_ptr_end)) {
         encoder->usr->error(encoder->usr, "lz encoder io reset failed\n");
@@ -607,6 +623,8 @@ void lz_decode_begin(LzContext *lz, uint8_t *io_ptr, unsigned int num_io_bytes,
     encoder->width = decode_32(encoder);
     encoder->height = decode_32(encoder);
     encoder->stride = decode_32(encoder);
+    lz_check_sizes(encoder);
+
     *out_top_down = decode_32(encoder);
 
     *out_width = encoder->width;
-- 
2.17.1