From dcd1e307d87a12d5de1d1dd6d1bb3d8bf6942a77 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sat, 31 Oct 2015 20:37:20 +0000 Subject: [PATCH] [WIN32K] Check the size of RLE bitmaps, while decompressing. Fixes possible buffer overrun. Patch by Kamil Hornicek CORE-8735 #resolve svn path=/trunk/; revision=69760 --- reactos/win32ss/gdi/eng/eng.h | 3 ++- reactos/win32ss/gdi/eng/rlecomp.c | 6 +++--- reactos/win32ss/gdi/ntgdi/bitmaps.c | 5 ++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/reactos/win32ss/gdi/eng/eng.h b/reactos/win32ss/gdi/eng/eng.h index c859c57ea0c..2a467b15115 100644 --- a/reactos/win32ss/gdi/eng/eng.h +++ b/reactos/win32ss/gdi/eng/eng.h @@ -52,4 +52,5 @@ DecompressBitmap( BYTE *CompressedBits, BYTE *UncompressedBits, LONG Delta, - ULONG iFormat); + ULONG iFormat, + ULONG cjSizeImage); diff --git a/reactos/win32ss/gdi/eng/rlecomp.c b/reactos/win32ss/gdi/eng/rlecomp.c index c00167c1403..881b4dd8afc 100644 --- a/reactos/win32ss/gdi/eng/rlecomp.c +++ b/reactos/win32ss/gdi/eng/rlecomp.c @@ -18,14 +18,14 @@ enum Rle_EscapeCodes RLE_DELTA = 2 /* Delta */ }; -VOID DecompressBitmap(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LONG Delta, ULONG Format) +VOID DecompressBitmap(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LONG Delta, ULONG Format, ULONG cjSizeImage) { INT x = 0; INT y = Size.cy - 1; INT c; INT length; INT width; - INT height = Size.cy - 1; + INT height = y; BYTE *begin = CompressedBits; BYTE *bits = CompressedBits; BYTE *temp; @@ -40,7 +40,7 @@ VOID DecompressBitmap(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, _SEH2_TRY { - while (y >= 0) + while (y >= 0 && (bits - begin) <= cjSizeImage) { length = (*bits++) >> shift; if (length) diff --git a/reactos/win32ss/gdi/ntgdi/bitmaps.c b/reactos/win32ss/gdi/ntgdi/bitmaps.c index 6b2093695da..e4c8a22dc02 100644 --- a/reactos/win32ss/gdi/ntgdi/bitmaps.c +++ b/reactos/win32ss/gdi/ntgdi/bitmaps.c @@ -107,7 +107,6 @@ GreCreateBitmapEx( pvCompressedBits = pvBits; pvBits = NULL; iFormat = (iFormat == BMF_4RLE) ? BMF_4BPP : BMF_8BPP; - cjSizeImage = 0; } /* Allocate a surface */ @@ -117,7 +116,7 @@ GreCreateBitmapEx( iFormat, fjBitmap, cjWidthBytes, - cjSizeImage, + pvCompressedBits ? 0 : cjSizeImage, pvBits); if (!psurf) { @@ -136,7 +135,7 @@ GreCreateBitmapEx( lDelta = WIDTH_BYTES_ALIGN32(nWidth, gajBitsPerFormat[iFormat]); pvBits = psurf->SurfObj.pvBits; - DecompressBitmap(sizl, pvCompressedBits, pvBits, lDelta, iFormat); + DecompressBitmap(sizl, pvCompressedBits, pvBits, lDelta, iFormat, cjSizeImage); } /* Get the handle for the bitmap */