update_decompress_brush: explicit output length checks
authorakallabeth <akallabeth@posteo.net>
Tue, 21 Apr 2020 08:18:22 +0000 (10:18 +0200)
committerakallabeth <akallabeth@posteo.net>
Tue, 5 May 2020 05:46:10 +0000 (07:46 +0200)
The output length was just assumed to be >= 256 bytes, with this
commit it is explicitly checked.

libfreerdp/core/orders.c

index 4bf3628..13ba137 100644 (file)
@@ -2495,23 +2495,21 @@ BOOL update_write_cache_glyph_v2_order(wStream* s, const CACHE_GLYPH_V2_ORDER* c
 
        return TRUE;
 }
-static BOOL update_decompress_brush(wStream* s, BYTE* output, BYTE bpp)
+static BOOL update_decompress_brush(wStream* s, BYTE* output, size_t outSize, BYTE bpp)
 {
-       UINT32 index;
        UINT32 x, y, k;
        BYTE byte = 0;
-       BYTE* palette;
-       UINT32 bytesPerPixel;
-       palette = Stream_Pointer(s) + 16;
-       bytesPerPixel = ((bpp + 1) / 8);
+       const BYTE* palette = Stream_Pointer(s) + 16;
+       const UINT32 bytesPerPixel = ((bpp + 1) / 8);
 
-       if (Stream_GetRemainingLength(s) < 16 + 7 * bytesPerPixel) // 64 / 4
+       if (!Stream_SafeSeek(s, 16ULL + 7ULL * bytesPerPixel)) // 64 / 4
                return FALSE;
 
        for (y = 7; y >= 0; y--)
        {
                for (x = 0; x < 8; x++)
                {
+                       UINT32 index;
                        if ((x % 4) == 0)
                                Stream_Read_UINT8(s, byte);
 
@@ -2519,14 +2517,15 @@ static BOOL update_decompress_brush(wStream* s, BYTE* output, BYTE bpp)
 
                        for (k = 0; k < bytesPerPixel; k++)
                        {
-                               output[((y * 8 + x) * bytesPerPixel) + k] = palette[(index * bytesPerPixel) + k];
+                               const size_t dstIndex = ((y * 8 + x) * bytesPerPixel) + k;
+                               const size_t srcIndex = (index * bytesPerPixel) + k;
+                               if (dstIndex >= outSize)
+                                       return FALSE;
+                               output[dstIndex] = palette[srcIndex];
                        }
                }
        }
 
-       /* Skip the palette */
-       Stream_Seek(s, 7 * bytesPerPixel);
-
        return TRUE;
 }
 static BOOL update_compress_brush(wStream* s, const BYTE* input, BYTE bpp)
@@ -2590,7 +2589,8 @@ static CACHE_BRUSH_ORDER* update_read_cache_brush_order(rdpUpdate* update, wStre
                        if (compressed != FALSE)
                        {
                                /* compressed brush */
-                               if (!update_decompress_brush(s, cache_brush->data, cache_brush->bpp))
+                               if (!update_decompress_brush(s, cache_brush->data, sizeof(cache_brush->data),
+                                                            cache_brush->bpp))
                                        goto fail;
                        }
                        else