| From: Robert Luberda <robert@debian.org> |
| Date: Tue, 29 May 2018 23:59:09 +0200 |
| Subject: Fix CVE-2018-10115 |
| |
| Apply "patch" taken from https://landave.io/files/patch_7zip_CVE-2018-10115.txt |
| |
| |
| Bugs-Debian: https://bugs.debian.org/897674 |
| --- |
| CPP/7zip/Compress/Rar1Decoder.cpp | 16 +++++++++++----- |
| CPP/7zip/Compress/Rar1Decoder.h | 3 ++- |
| CPP/7zip/Compress/Rar2Decoder.cpp | 17 +++++++++++++---- |
| CPP/7zip/Compress/Rar2Decoder.h | 3 ++- |
| CPP/7zip/Compress/Rar3Decoder.cpp | 19 +++++++++++++++---- |
| CPP/7zip/Compress/Rar3Decoder.h | 3 ++- |
| CPP/7zip/Compress/Rar5Decoder.cpp | 8 ++++++++ |
| CPP/7zip/Compress/Rar5Decoder.h | 1 + |
| 8 files changed, 54 insertions(+), 16 deletions(-) |
| |
| diff --git a/CPP/7zip/Compress/Rar1Decoder.cpp b/CPP/7zip/Compress/Rar1Decoder.cpp |
| index 68030c7..8c890c8 100644 |
| --- a/CPP/7zip/Compress/Rar1Decoder.cpp |
| +++ b/CPP/7zip/Compress/Rar1Decoder.cpp |
| @@ -29,7 +29,7 @@ public: |
| }; |
| */ |
| |
| -CDecoder::CDecoder(): m_IsSolid(false), _errorMode(false) { } |
| +CDecoder::CDecoder(): _isSolid(false), _solidAllowed(false), _errorMode(false) { } |
| |
| void CDecoder::InitStructures() |
| { |
| @@ -345,7 +345,7 @@ void CDecoder::GetFlagsBuf() |
| |
| void CDecoder::InitData() |
| { |
| - if (!m_IsSolid) |
| + if (!_isSolid) |
| { |
| AvrPlcB = AvrLn1 = AvrLn2 = AvrLn3 = NumHuf = Buf60 = 0; |
| AvrPlc = 0x3500; |
| @@ -391,6 +391,11 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * |
| if (inSize == NULL || outSize == NULL) |
| return E_INVALIDARG; |
| |
| + if (_isSolid && !_solidAllowed) |
| + return S_FALSE; |
| + |
| + _solidAllowed = false; |
| + |
| if (!m_OutWindowStream.Create(kHistorySize)) |
| return E_OUTOFMEMORY; |
| if (!m_InBitStream.Create(1 << 20)) |
| @@ -398,13 +403,13 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * |
| |
| m_UnpackSize = (Int64)*outSize; |
| m_OutWindowStream.SetStream(outStream); |
| - m_OutWindowStream.Init(m_IsSolid); |
| + m_OutWindowStream.Init(_isSolid); |
| m_InBitStream.SetStream(inStream); |
| m_InBitStream.Init(); |
| |
| // CCoderReleaser coderReleaser(this); |
| InitData(); |
| - if (!m_IsSolid) |
| + if (!_isSolid) |
| { |
| _errorMode = false; |
| InitStructures(); |
| @@ -475,6 +480,7 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * |
| } |
| if (m_UnpackSize < 0) |
| return S_FALSE; |
| + _solidAllowed = true; |
| return m_OutWindowStream.Flush(); |
| } |
| |
| @@ -491,7 +497,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) |
| { |
| if (size < 1) |
| return E_INVALIDARG; |
| - m_IsSolid = ((data[0] & 1) != 0); |
| + _isSolid = ((data[0] & 1) != 0); |
| return S_OK; |
| } |
| |
| diff --git a/CPP/7zip/Compress/Rar1Decoder.h b/CPP/7zip/Compress/Rar1Decoder.h |
| index 01b606b..8abb3a3 100644 |
| --- a/CPP/7zip/Compress/Rar1Decoder.h |
| +++ b/CPP/7zip/Compress/Rar1Decoder.h |
| @@ -38,7 +38,8 @@ public: |
| UInt32 LastLength; |
| |
| Int64 m_UnpackSize; |
| - bool m_IsSolid; |
| + bool _isSolid; |
| + bool _solidAllowed; |
| bool _errorMode; |
| |
| UInt32 ReadBits(int numBits); |
| diff --git a/CPP/7zip/Compress/Rar2Decoder.cpp b/CPP/7zip/Compress/Rar2Decoder.cpp |
| index 0580c8d..be8d842 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), |
| + _isSolid(false), |
| + _solidAllowed(false), |
| m_TablesOK(false) |
| { |
| } |
| @@ -320,6 +321,10 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * |
| if (inSize == NULL || outSize == NULL) |
| return E_INVALIDARG; |
| |
| + if (_isSolid && !_solidAllowed) |
| + return S_FALSE; |
| + _solidAllowed = false; |
| + |
| if (!m_OutWindowStream.Create(kHistorySize)) |
| return E_OUTOFMEMORY; |
| if (!m_InBitStream.Create(1 << 20)) |
| @@ -330,12 +335,12 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * |
| UInt64 pos = 0, unPackSize = *outSize; |
| |
| m_OutWindowStream.SetStream(outStream); |
| - m_OutWindowStream.Init(m_IsSolid); |
| + m_OutWindowStream.Init(_isSolid); |
| m_InBitStream.SetStream(inStream); |
| m_InBitStream.Init(); |
| |
| // CCoderReleaser coderReleaser(this); |
| - if (!m_IsSolid) |
| + if (!_isSolid) |
| { |
| InitStructures(); |
| if (unPackSize == 0) |
| @@ -343,6 +348,7 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * |
| if (m_InBitStream.GetProcessedSize() + 2 <= m_PackSize) // test it: probably incorrect; |
| if (!ReadTables()) |
| return S_FALSE; |
| + _solidAllowed = true; |
| return S_OK; |
| } |
| if (!ReadTables()) |
| @@ -386,6 +392,9 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * |
| |
| if (!ReadLastTables()) |
| return S_FALSE; |
| + |
| + _solidAllowed = true; |
| + |
| return m_OutWindowStream.Flush(); |
| } |
| |
| @@ -402,7 +411,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) |
| { |
| if (size < 1) |
| return E_INVALIDARG; |
| - m_IsSolid = ((data[0] & 1) != 0); |
| + _isSolid = ((data[0] & 1) != 0); |
| return S_OK; |
| } |
| |
| diff --git a/CPP/7zip/Compress/Rar2Decoder.h b/CPP/7zip/Compress/Rar2Decoder.h |
| index 0e9005f..370bce2 100644 |
| --- a/CPP/7zip/Compress/Rar2Decoder.h |
| +++ b/CPP/7zip/Compress/Rar2Decoder.h |
| @@ -138,7 +138,8 @@ class CDecoder : |
| Byte m_LastLevels[kMaxTableSize]; |
| |
| UInt64 m_PackSize; |
| - bool m_IsSolid; |
| + bool _isSolid; |
| + bool _solidAllowed; |
| bool m_TablesOK; |
| |
| void InitStructures(); |
| diff --git a/CPP/7zip/Compress/Rar3Decoder.cpp b/CPP/7zip/Compress/Rar3Decoder.cpp |
| index 6cb8a6a..7b85833 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), |
| + _isSolid(false), |
| + _solidAllowed(false), |
| _errorMode(false) |
| { |
| Ppmd7_Construct(&_ppmd); |
| @@ -821,7 +822,7 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) |
| { |
| _writtenFileSize = 0; |
| _unsupportedFilter = false; |
| - if (!m_IsSolid) |
| + if (!_isSolid) |
| { |
| _lzSize = 0; |
| _winPos = 0; |
| @@ -840,12 +841,15 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) |
| if (_errorMode) |
| return S_FALSE; |
| |
| - if (!m_IsSolid || !TablesRead) |
| + if (!_isSolid || !TablesRead) |
| { |
| bool keepDecompressing; |
| RINOK(ReadTables(keepDecompressing)); |
| if (!keepDecompressing) |
| + { |
| + _solidAllowed = true; |
| return S_OK; |
| + } |
| } |
| |
| for (;;) |
| @@ -870,6 +874,9 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) |
| if (!keepDecompressing) |
| break; |
| } |
| + |
| + _solidAllowed = true; |
| + |
| RINOK(WriteBuf()); |
| UInt64 packSize = m_InBitStream.BitDecoder.GetProcessedSize(); |
| RINOK(progress->SetRatioInfo(&packSize, &_writtenFileSize)); |
| @@ -890,6 +897,10 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream |
| if (!inSize) |
| return E_INVALIDARG; |
| |
| + if (_isSolid && !_solidAllowed) |
| + return S_FALSE; |
| + _solidAllowed = false; |
| + |
| if (!_vmData) |
| { |
| _vmData = (Byte *)::MidAlloc(kVmDataSizeMax + kVmCodeSizeMax); |
| @@ -928,7 +939,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) |
| { |
| if (size < 1) |
| return E_INVALIDARG; |
| - m_IsSolid = ((data[0] & 1) != 0); |
| + _isSolid = ((data[0] & 1) != 0); |
| return S_OK; |
| } |
| |
| diff --git a/CPP/7zip/Compress/Rar3Decoder.h b/CPP/7zip/Compress/Rar3Decoder.h |
| index 2f72d7d..32c8943 100644 |
| --- a/CPP/7zip/Compress/Rar3Decoder.h |
| +++ b/CPP/7zip/Compress/Rar3Decoder.h |
| @@ -191,7 +191,8 @@ class CDecoder: |
| CRecordVector<CTempFilter *> _tempFilters; |
| UInt32 _lastFilter; |
| |
| - bool m_IsSolid; |
| + bool _isSolid; |
| + bool _solidAllowed; |
| bool _errorMode; |
| |
| bool _lzMode; |
| diff --git a/CPP/7zip/Compress/Rar5Decoder.cpp b/CPP/7zip/Compress/Rar5Decoder.cpp |
| index dc8830f..a826d5a 100644 |
| --- a/CPP/7zip/Compress/Rar5Decoder.cpp |
| +++ b/CPP/7zip/Compress/Rar5Decoder.cpp |
| @@ -72,6 +72,7 @@ CDecoder::CDecoder(): |
| _writtenFileSize(0), |
| _dictSizeLog(0), |
| _isSolid(false), |
| + _solidAllowed(false), |
| _wasInit(false), |
| _inputBuf(NULL) |
| { |
| @@ -801,7 +802,10 @@ HRESULT CDecoder::CodeReal() |
| */ |
| |
| if (res == S_OK) |
| + { |
| + _solidAllowed = true; |
| res = res2; |
| + } |
| |
| if (res == S_OK && _unpackSize_Defined && _writtenFileSize != _unpackSize) |
| return S_FALSE; |
| @@ -821,6 +825,10 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream |
| { |
| try |
| { |
| + if (_isSolid && !_solidAllowed) |
| + return S_FALSE; |
| + _solidAllowed = false; |
| + |
| if (_dictSizeLog >= sizeof(size_t) * 8) |
| return E_NOTIMPL; |
| |
| diff --git a/CPP/7zip/Compress/Rar5Decoder.h b/CPP/7zip/Compress/Rar5Decoder.h |
| index b0a4dd1..3db5018 100644 |
| --- a/CPP/7zip/Compress/Rar5Decoder.h |
| +++ b/CPP/7zip/Compress/Rar5Decoder.h |
| @@ -271,6 +271,7 @@ class CDecoder: |
| Byte _dictSizeLog; |
| bool _tableWasFilled; |
| bool _isSolid; |
| + bool _solidAllowed; |
| bool _wasInit; |
| |
| UInt32 _reps[kNumReps]; |