From 82ac0164f330c08ddd9a6ef6f3dbf846c4b79def Mon Sep 17 00:00:00 2001 From: Armin Novak <anovak@thincast.com> Date: Sat, 5 Aug 2023 10:53:29 +0200 Subject: [PATCH] [codec,nsc] fix missing plane length check reported by @pwn2carr (cherry picked from commit 89cd622426b3fcac64b9203e69f9f407cc19760e) --- libfreerdp/codec/nsc.c | 71 +++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/libfreerdp/codec/nsc.c b/libfreerdp/codec/nsc.c index dc3a978ed243..66aa275f1434 100644 --- a/libfreerdp/codec/nsc.c +++ b/libfreerdp/codec/nsc.c @@ -29,6 +29,8 @@ #include <string.h> #include <winpr/crt.h> +#include <winpr/assert.h> +#include <winpr/stream.h> #include <freerdp/codec/nsc.h> #include <freerdp/codec/color.h> @@ -38,6 +40,12 @@ #include "nsc_sse2.h" +#if !defined(Stream_CheckAndLogRequiredLengthWLog) +#define Stream_CheckAndLogRequiredLengthWLog(log, s, len) \ + Stream_CheckAndLogRequiredLengthWLogEx(log, WLOG_WARN, s, len, "%s(%s:%d)", __FUNCTION__, \ + __FILE__, __LINE__) +#endif + #ifndef NSC_INIT_SIMD #define NSC_INIT_SIMD(_nsc_context) \ do \ @@ -175,20 +183,16 @@ static BOOL nsc_rle_decode(BYTE* in, BYTE* out, UINT32 outSize, UINT32 originalS static BOOL nsc_rle_decompress_data(NSC_CONTEXT* context) { - UINT16 i; - BYTE* rle; - UINT32 planeSize; - UINT32 originalSize; - if (!context) return FALSE; - rle = context->Planes; + BYTE* rle = context->Planes; + WINPR_ASSERT(rle); - for (i = 0; i < 4; i++) + for (size_t i = 0; i < 4; i++) { - originalSize = context->OrgByteCount[i]; - planeSize = context->PlaneByteCount[i]; + const UINT32 originalSize = context->OrgByteCount[i]; + const UINT32 planeSize = context->PlaneByteCount[i]; if (planeSize == 0) { @@ -219,64 +223,63 @@ static BOOL nsc_rle_decompress_data(NSC_CONTEXT* context) static BOOL nsc_stream_initialize(NSC_CONTEXT* context, wStream* s) { - int i; - - if (Stream_GetRemainingLength(s) < 20) + WINPR_ASSERT(context); + WINPR_ASSERT(context->priv); + if (!Stream_CheckAndLogRequiredLengthWLog(context->priv->log, s, 20)) return FALSE; - for (i = 0; i < 4; i++) + size_t total = 0; + for (size_t i = 0; i < 4; i++) + { Stream_Read_UINT32(s, context->PlaneByteCount[i]); + total += context->PlaneByteCount[i]; + } Stream_Read_UINT8(s, context->ColorLossLevel); /* ColorLossLevel (1 byte) */ Stream_Read_UINT8(s, context->ChromaSubsamplingLevel); /* ChromaSubsamplingLevel (1 byte) */ Stream_Seek(s, 2); /* Reserved (2 bytes) */ context->Planes = Stream_Pointer(s); - return TRUE; + return Stream_CheckAndLogRequiredLengthWLog(context->priv->log, s, total); } static BOOL nsc_context_initialize(NSC_CONTEXT* context, wStream* s) { - int i; - UINT32 length; - UINT32 tempWidth; - UINT32 tempHeight; - if (!nsc_stream_initialize(context, s)) return FALSE; - length = context->width * context->height * 4; + const size_t blength = context->width * context->height * 4; if (!context->BitmapData) { - context->BitmapData = calloc(1, length + 16); + context->BitmapData = calloc(1, blength + 16); if (!context->BitmapData) return FALSE; - context->BitmapDataLength = length; + context->BitmapDataLength = blength; } - else if (length > context->BitmapDataLength) + else if (blength > context->BitmapDataLength) { void* tmp; - tmp = realloc(context->BitmapData, length + 16); + tmp = realloc(context->BitmapData, blength + 16); if (!tmp) return FALSE; context->BitmapData = tmp; - context->BitmapDataLength = length; + context->BitmapDataLength = blength; } - tempWidth = ROUND_UP_TO(context->width, 8); - tempHeight = ROUND_UP_TO(context->height, 2); + const UINT32 tempWidth = ROUND_UP_TO(context->width, 8); + const UINT32 tempHeight = ROUND_UP_TO(context->height, 2); /* The maximum length a decoded plane can reach in all cases */ - length = tempWidth * tempHeight; + const size_t plength = tempWidth * tempHeight; - if (length > context->priv->PlaneBuffersLength) + if (plength > context->priv->PlaneBuffersLength) { - for (i = 0; i < 4; i++) + for (size_t i = 0; i < 4; i++) { - void* tmp = (BYTE*)realloc(context->priv->PlaneBuffers[i], length); + void* tmp = (BYTE*)realloc(context->priv->PlaneBuffers[i], plength); if (!tmp) return FALSE; @@ -284,13 +287,11 @@ static BOOL nsc_context_initialize(NSC_CONTEXT* context, wStream* s) context->priv->PlaneBuffers[i] = tmp; } - context->priv->PlaneBuffersLength = length; + context->priv->PlaneBuffersLength = plength; } - for (i = 0; i < 4; i++) - { + for (size_t i = 0; i < 4; i++) context->OrgByteCount[i] = context->width * context->height; - } if (context->ChromaSubsamplingLevel) {