Patch based on analysis of the fix in upstream 7-zip at https://landave.io/files/patch_7zip_CVE-2018-10115.txt diff -pruN '--exclude=*.orig' p7zip_16.02~/CPP/7zip/Compress/Rar1Decoder.cpp p7zip_16.02/CPP/7zip/Compress/Rar1Decoder.cpp --- p7zip_16.02~/CPP/7zip/Compress/Rar1Decoder.cpp 2018-05-02 15:06:58.034027678 +0000 +++ p7zip_16.02/CPP/7zip/Compress/Rar1Decoder.cpp 2018-05-02 15:06:58.162661972 +0000 @@ -29,7 +29,12 @@ public: }; */ -CDecoder::CDecoder(): m_IsSolid(false), _errorMode(false) { } +CDecoder::CDecoder(): + m_IsSolid(false), + m_solidAllowed(false), + _errorMode(false) +{ +} void CDecoder::InitStructures() { @@ -391,6 +396,11 @@ HRESULT CDecoder::CodeReal(ISequentialIn if (inSize == NULL || outSize == NULL) return E_INVALIDARG; + if (m_IsSolid && !m_solidAllowed) + return S_FALSE; + + m_solidAllowed = false; + if (!m_OutWindowStream.Create(kHistorySize)) return E_OUTOFMEMORY; if (!m_InBitStream.Create(1 << 20)) @@ -473,6 +483,7 @@ HRESULT CDecoder::CodeReal(ISequentialIn } } } + m_solidAllowed = true; if (m_UnpackSize < 0) return S_FALSE; return m_OutWindowStream.Flush(); diff -pruN '--exclude=*.orig' p7zip_16.02~/CPP/7zip/Compress/Rar1Decoder.h p7zip_16.02/CPP/7zip/Compress/Rar1Decoder.h --- p7zip_16.02~/CPP/7zip/Compress/Rar1Decoder.h 2018-05-02 15:06:58.034273736 +0000 +++ p7zip_16.02/CPP/7zip/Compress/Rar1Decoder.h 2018-05-02 15:06:58.162871572 +0000 @@ -39,6 +39,7 @@ public: Int64 m_UnpackSize; bool m_IsSolid; + bool m_solidAllowed; bool _errorMode; UInt32 ReadBits(int numBits); diff -pruN '--exclude=*.orig' p7zip_16.02~/CPP/7zip/Compress/Rar2Decoder.cpp p7zip_16.02/CPP/7zip/Compress/Rar2Decoder.cpp --- p7zip_16.02~/CPP/7zip/Compress/Rar2Decoder.cpp 2018-05-02 15:06:58.034541629 +0000 +++ p7zip_16.02/CPP/7zip/Compress/Rar2Decoder.cpp 2018-05-02 15:06:58.163128844 +0000 @@ -81,6 +81,7 @@ static const UInt32 kWindowReservSize = CDecoder::CDecoder(): m_IsSolid(false), + m_solidAllowed(false), m_TablesOK(false) { } @@ -320,6 +321,10 @@ HRESULT CDecoder::CodeReal(ISequentialIn if (inSize == NULL || outSize == NULL) return E_INVALIDARG; + if (m_IsSolid && !m_solidAllowed) + return S_FALSE; + m_solidAllowed = false; + if (!m_OutWindowStream.Create(kHistorySize)) return E_OUTOFMEMORY; if (!m_InBitStream.Create(1 << 20)) @@ -343,6 +348,7 @@ HRESULT CDecoder::CodeReal(ISequentialIn if (m_InBitStream.GetProcessedSize() + 2 <= m_PackSize) // test it: probably incorrect; if (!ReadTables()) return S_FALSE; + m_solidAllowed = true; return S_OK; } if (!ReadTables()) @@ -386,6 +392,7 @@ HRESULT CDecoder::CodeReal(ISequentialIn if (!ReadLastTables()) return S_FALSE; + m_solidAllowed = true; return m_OutWindowStream.Flush(); } diff -pruN '--exclude=*.orig' p7zip_16.02~/CPP/7zip/Compress/Rar2Decoder.h p7zip_16.02/CPP/7zip/Compress/Rar2Decoder.h --- p7zip_16.02~/CPP/7zip/Compress/Rar2Decoder.h 2018-05-02 15:06:58.034736908 +0000 +++ p7zip_16.02/CPP/7zip/Compress/Rar2Decoder.h 2018-05-02 15:06:58.163323313 +0000 @@ -139,6 +139,7 @@ class CDecoder : UInt64 m_PackSize; bool m_IsSolid; + bool m_solidAllowed; bool m_TablesOK; void InitStructures(); diff -pruN '--exclude=*.orig' p7zip_16.02~/CPP/7zip/Compress/Rar3Decoder.cpp p7zip_16.02/CPP/7zip/Compress/Rar3Decoder.cpp --- p7zip_16.02~/CPP/7zip/Compress/Rar3Decoder.cpp 2018-05-02 15:06:58.035151069 +0000 +++ p7zip_16.02/CPP/7zip/Compress/Rar3Decoder.cpp 2018-05-02 15:06:58.163692811 +0000 @@ -93,6 +93,7 @@ CDecoder::CDecoder(): _vmData(0), _vmCode(0), m_IsSolid(false), + m_solidAllowed(false), _errorMode(false) { Ppmd7_Construct(&_ppmd); @@ -845,7 +846,10 @@ HRESULT CDecoder::CodeReal(ICompressProg bool keepDecompressing; RINOK(ReadTables(keepDecompressing)); if (!keepDecompressing) + { + m_solidAllowed = true; return S_OK; + } } for (;;) @@ -870,6 +874,7 @@ HRESULT CDecoder::CodeReal(ICompressProg if (!keepDecompressing) break; } + m_solidAllowed = true; RINOK(WriteBuf()); UInt64 packSize = m_InBitStream.BitDecoder.GetProcessedSize(); RINOK(progress->SetRatioInfo(&packSize, &_writtenFileSize)); @@ -890,6 +895,10 @@ STDMETHODIMP CDecoder::Code(ISequentialI if (!inSize) return E_INVALIDARG; + if (m_IsSolid && !m_solidAllowed) + return S_FALSE; + m_solidAllowed = false; + if (!_vmData) { _vmData = (Byte *)::MidAlloc(kVmDataSizeMax + kVmCodeSizeMax); diff -pruN '--exclude=*.orig' p7zip_16.02~/CPP/7zip/Compress/Rar3Decoder.h p7zip_16.02/CPP/7zip/Compress/Rar3Decoder.h --- p7zip_16.02~/CPP/7zip/Compress/Rar3Decoder.h 2018-05-02 15:06:58.035371032 +0000 +++ p7zip_16.02/CPP/7zip/Compress/Rar3Decoder.h 2018-05-02 15:06:58.163919947 +0000 @@ -192,6 +192,7 @@ class CDecoder: UInt32 _lastFilter; bool m_IsSolid; + bool m_solidAllowed; bool _errorMode; bool _lzMode; diff -pruN '--exclude=*.orig' p7zip_16.02~/CPP/7zip/Compress/Rar5Decoder.cpp p7zip_16.02/CPP/7zip/Compress/Rar5Decoder.cpp --- p7zip_16.02~/CPP/7zip/Compress/Rar5Decoder.cpp 2016-05-20 08:20:04.000000000 +0000 +++ p7zip_16.02/CPP/7zip/Compress/Rar5Decoder.cpp 2018-05-02 15:06:58.164239702 +0000 @@ -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,9 @@ STDMETHODIMP CDecoder::Code(ISequentialI { try { + if (_isSolid && !_solidAllowed) + return S_FALSE; + _solidAllowed = false; if (_dictSizeLog >= sizeof(size_t) * 8) return E_NOTIMPL; diff -pruN '--exclude=*.orig' p7zip_16.02~/CPP/7zip/Compress/Rar5Decoder.h p7zip_16.02/CPP/7zip/Compress/Rar5Decoder.h --- p7zip_16.02~/CPP/7zip/Compress/Rar5Decoder.h 2015-09-01 18:04:50.000000000 +0000 +++ p7zip_16.02/CPP/7zip/Compress/Rar5Decoder.h 2018-05-02 15:06:58.164455518 +0000 @@ -271,6 +271,7 @@ class CDecoder: Byte _dictSizeLog; bool _tableWasFilled; bool _isSolid; + bool _solidAllowed; bool _wasInit; UInt32 _reps[kNumReps];