From 7c0c905683204dd6a0ebab34fcd649454e07dfb8 Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Thu, 13 Nov 2014 14:48:47 +0100 Subject: [PATCH] libfreerdp-codec: fix mppc decompression * protect against history buffer overflows * fix replicating copy (CopyOffset can be > HistoryBufferSize!) --- libfreerdp/codec/mppc.c | 43 ++++++++++++++--------------------------- 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/libfreerdp/codec/mppc.c b/libfreerdp/codec/mppc.c index f975b2303..05e13750a 100644 --- a/libfreerdp/codec/mppc.c +++ b/libfreerdp/codec/mppc.c @@ -26,6 +26,7 @@ #include #include +#include #include #define TAG FREERDP_TAG("codec.mppc") @@ -125,6 +126,12 @@ int mppc_decompress(MPPC_CONTEXT* mppc, BYTE* pSrcData, UINT32 SrcSize, BYTE** p * Literal Encoding */ + if (HistoryPtr > HistoryBufferEnd) + { + WLog_ERR(TAG, "history buffer index out of range"); + return -1004; + } + if ((accumulator & 0x80000000) == 0x00000000) { /** @@ -418,39 +425,17 @@ int mppc_decompress(MPPC_CONTEXT* mppc, BYTE* pSrcData, UINT32 SrcSize, BYTE** p WLog_DBG(TAG, "<%d,%d>", (int) CopyOffset, (int) LengthOfMatch); #endif - SrcPtr = HistoryPtr - CopyOffset; - - if (SrcPtr >= HistoryBuffer) + if ((HistoryPtr + LengthOfMatch - 1) > HistoryBufferEnd) { - while (LengthOfMatch > 0) - { - *(HistoryPtr) = *SrcPtr; - - HistoryPtr++; - SrcPtr++; - - LengthOfMatch--; - } + WLog_ERR(TAG, "history buffer overflow"); + return -1005; } - else - { - SrcPtr = HistoryBufferEnd - (CopyOffset - (HistoryPtr - HistoryBuffer)); - SrcPtr++; - while (LengthOfMatch && (SrcPtr <= HistoryBufferEnd)) - { - *HistoryPtr++ = *SrcPtr++; - LengthOfMatch--; - } + SrcPtr = &HistoryBuffer[(HistoryPtr - HistoryBuffer - CopyOffset) & (CompressionLevel ? 0xFFFF : 0x1FFF)]; - SrcPtr = HistoryBuffer; - - while (LengthOfMatch > 0) - { - *HistoryPtr++ = *SrcPtr++; - LengthOfMatch--; - } - } + do { + *HistoryPtr++ = *SrcPtr++; + } while (--LengthOfMatch); } *pDstSize = (UINT32) (HistoryPtr - mppc->HistoryPtr);