123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- From: Robert Luberda <robert@debian.org>
- Date: Sun, 28 Jan 2018 23:47:40 +0100
- Subject: CVE-2018-5996
- Hopefully fix Memory Corruptions via RAR PPMd (CVE-2018-5996) by
- applying a few changes from 7Zip 18.00-beta.
- Bug-Debian: https://bugs.debian.org/#888314
- Signed-off-by: André Hentschel <nerv@dawncrow.de>
- ---
- CPP/7zip/Compress/Rar1Decoder.cpp | 13 +++++++++----
- CPP/7zip/Compress/Rar1Decoder.h | 1 +
- CPP/7zip/Compress/Rar2Decoder.cpp | 10 +++++++++-
- CPP/7zip/Compress/Rar2Decoder.h | 1 +
- CPP/7zip/Compress/Rar3Decoder.cpp | 23 ++++++++++++++++++++---
- CPP/7zip/Compress/Rar3Decoder.h | 2 ++
- 6 files changed, 42 insertions(+), 8 deletions(-)
- diff --git a/CPP/7zip/Compress/Rar1Decoder.cpp b/CPP/7zip/Compress/Rar1Decoder.cpp
- index 1aaedcc..68030c7 100644
- --- a/CPP/7zip/Compress/Rar1Decoder.cpp
- +++ b/CPP/7zip/Compress/Rar1Decoder.cpp
- @@ -29,7 +29,7 @@ public:
- };
- */
-
- -CDecoder::CDecoder(): m_IsSolid(false) { }
- +CDecoder::CDecoder(): m_IsSolid(false), _errorMode(false) { }
-
- void CDecoder::InitStructures()
- {
- @@ -406,9 +406,14 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
- InitData();
- if (!m_IsSolid)
- {
- + _errorMode = false;
- InitStructures();
- InitHuff();
- }
- +
- + if (_errorMode)
- + return S_FALSE;
- +
- if (m_UnpackSize > 0)
- {
- GetFlagsBuf();
- @@ -477,9 +482,9 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
- const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
- {
- try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
- - catch(const CInBufferException &e) { return e.ErrorCode; }
- - catch(const CLzOutWindowException &e) { return e.ErrorCode; }
- - catch(...) { return S_FALSE; }
- + catch(const CInBufferException &e) { _errorMode = true; return e.ErrorCode; }
- + catch(const CLzOutWindowException &e) { _errorMode = true; return e.ErrorCode; }
- + catch(...) { _errorMode = true; return S_FALSE; }
- }
-
- STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
- diff --git a/CPP/7zip/Compress/Rar1Decoder.h b/CPP/7zip/Compress/Rar1Decoder.h
- index 630f089..01b606b 100644
- --- a/CPP/7zip/Compress/Rar1Decoder.h
- +++ b/CPP/7zip/Compress/Rar1Decoder.h
- @@ -39,6 +39,7 @@ public:
-
- Int64 m_UnpackSize;
- bool m_IsSolid;
- + bool _errorMode;
-
- UInt32 ReadBits(int numBits);
- HRESULT CopyBlock(UInt32 distance, UInt32 len);
- diff --git a/CPP/7zip/Compress/Rar2Decoder.cpp b/CPP/7zip/Compress/Rar2Decoder.cpp
- index b3f2b4b..0580c8d 100644
- --- a/CPP/7zip/Compress/Rar2Decoder.cpp
- +++ b/CPP/7zip/Compress/Rar2Decoder.cpp
- @@ -80,7 +80,8 @@ static const UInt32 kHistorySize = 1 << 20;
- static const UInt32 kWindowReservSize = (1 << 22) + 256;
-
- CDecoder::CDecoder():
- - m_IsSolid(false)
- + m_IsSolid(false),
- + m_TablesOK(false)
- {
- }
-
- @@ -100,6 +101,8 @@ UInt32 CDecoder::ReadBits(unsigned numBits) { return m_InBitStream.ReadBits(numB
-
- bool CDecoder::ReadTables(void)
- {
- + m_TablesOK = false;
- +
- Byte levelLevels[kLevelTableSize];
- Byte newLevels[kMaxTableSize];
- m_AudioMode = (ReadBits(1) == 1);
- @@ -170,6 +173,8 @@ bool CDecoder::ReadTables(void)
- }
-
- memcpy(m_LastLevels, newLevels, kMaxTableSize);
- + m_TablesOK = true;
- +
- return true;
- }
-
- @@ -344,6 +349,9 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
- return S_FALSE;
- }
-
- + if (!m_TablesOK)
- + return S_FALSE;
- +
- UInt64 startPos = m_OutWindowStream.GetProcessedSize();
- while (pos < unPackSize)
- {
- diff --git a/CPP/7zip/Compress/Rar2Decoder.h b/CPP/7zip/Compress/Rar2Decoder.h
- index 3a0535c..0e9005f 100644
- --- a/CPP/7zip/Compress/Rar2Decoder.h
- +++ b/CPP/7zip/Compress/Rar2Decoder.h
- @@ -139,6 +139,7 @@ class CDecoder :
-
- UInt64 m_PackSize;
- bool m_IsSolid;
- + bool m_TablesOK;
-
- void InitStructures();
- UInt32 ReadBits(unsigned numBits);
- diff --git a/CPP/7zip/Compress/Rar3Decoder.cpp b/CPP/7zip/Compress/Rar3Decoder.cpp
- index 3bf2513..6cb8a6a 100644
- --- a/CPP/7zip/Compress/Rar3Decoder.cpp
- +++ b/CPP/7zip/Compress/Rar3Decoder.cpp
- @@ -92,7 +92,8 @@ CDecoder::CDecoder():
- _writtenFileSize(0),
- _vmData(0),
- _vmCode(0),
- - m_IsSolid(false)
- + m_IsSolid(false),
- + _errorMode(false)
- {
- Ppmd7_Construct(&_ppmd);
- }
- @@ -545,6 +546,9 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing)
- return InitPPM();
- }
-
- + TablesRead = false;
- + TablesOK = false;
- +
- _lzMode = true;
- PrevAlignBits = 0;
- PrevAlignCount = 0;
- @@ -606,6 +610,9 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing)
- }
- }
- }
- + if (InputEofError())
- + return S_FALSE;
- +
- TablesRead = true;
-
- // original code has check here:
- @@ -623,6 +630,9 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing)
- RIF(m_LenDecoder.Build(&newLevels[kMainTableSize + kDistTableSize + kAlignTableSize]));
-
- memcpy(m_LastLevels, newLevels, kTablesSizesSum);
- +
- + TablesOK = true;
- +
- return S_OK;
- }
-
- @@ -824,7 +834,12 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress)
- PpmEscChar = 2;
- PpmError = true;
- InitFilters();
- + _errorMode = false;
- }
- +
- + if (_errorMode)
- + return S_FALSE;
- +
- if (!m_IsSolid || !TablesRead)
- {
- bool keepDecompressing;
- @@ -838,6 +853,8 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress)
- bool keepDecompressing;
- if (_lzMode)
- {
- + if (!TablesOK)
- + return S_FALSE;
- RINOK(DecodeLZ(keepDecompressing))
- }
- else
- @@ -901,8 +918,8 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
- _unpackSize = outSize ? *outSize : (UInt64)(Int64)-1;
- return CodeReal(progress);
- }
- - catch(const CInBufferException &e) { return e.ErrorCode; }
- - catch(...) { return S_FALSE; }
- + catch(const CInBufferException &e) { _errorMode = true; return e.ErrorCode; }
- + catch(...) { _errorMode = true; return S_FALSE; }
- // CNewException is possible here. But probably CNewException is caused
- // by error in data stream.
- }
- diff --git a/CPP/7zip/Compress/Rar3Decoder.h b/CPP/7zip/Compress/Rar3Decoder.h
- index c130cec..2f72d7d 100644
- --- a/CPP/7zip/Compress/Rar3Decoder.h
- +++ b/CPP/7zip/Compress/Rar3Decoder.h
- @@ -192,6 +192,7 @@ class CDecoder:
- UInt32 _lastFilter;
-
- bool m_IsSolid;
- + bool _errorMode;
-
- bool _lzMode;
- bool _unsupportedFilter;
- @@ -200,6 +201,7 @@ class CDecoder:
- UInt32 PrevAlignCount;
-
- bool TablesRead;
- + bool TablesOK;
-
- CPpmd7 _ppmd;
- int PpmEscChar;
|