0003-CVE-2018-5996.patch 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. From: Robert Luberda <robert@debian.org>
  2. Date: Sun, 28 Jan 2018 23:47:40 +0100
  3. Subject: CVE-2018-5996
  4. Hopefully fix Memory Corruptions via RAR PPMd (CVE-2018-5996) by
  5. applying a few changes from 7Zip 18.00-beta.
  6. Bug-Debian: https://bugs.debian.org/#888314
  7. Signed-off-by: André Hentschel <nerv@dawncrow.de>
  8. ---
  9. CPP/7zip/Compress/Rar1Decoder.cpp | 13 +++++++++----
  10. CPP/7zip/Compress/Rar1Decoder.h | 1 +
  11. CPP/7zip/Compress/Rar2Decoder.cpp | 10 +++++++++-
  12. CPP/7zip/Compress/Rar2Decoder.h | 1 +
  13. CPP/7zip/Compress/Rar3Decoder.cpp | 23 ++++++++++++++++++++---
  14. CPP/7zip/Compress/Rar3Decoder.h | 2 ++
  15. 6 files changed, 42 insertions(+), 8 deletions(-)
  16. diff --git a/CPP/7zip/Compress/Rar1Decoder.cpp b/CPP/7zip/Compress/Rar1Decoder.cpp
  17. index 1aaedcc..68030c7 100644
  18. --- a/CPP/7zip/Compress/Rar1Decoder.cpp
  19. +++ b/CPP/7zip/Compress/Rar1Decoder.cpp
  20. @@ -29,7 +29,7 @@ public:
  21. };
  22. */
  23. -CDecoder::CDecoder(): m_IsSolid(false) { }
  24. +CDecoder::CDecoder(): m_IsSolid(false), _errorMode(false) { }
  25. void CDecoder::InitStructures()
  26. {
  27. @@ -406,9 +406,14 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
  28. InitData();
  29. if (!m_IsSolid)
  30. {
  31. + _errorMode = false;
  32. InitStructures();
  33. InitHuff();
  34. }
  35. +
  36. + if (_errorMode)
  37. + return S_FALSE;
  38. +
  39. if (m_UnpackSize > 0)
  40. {
  41. GetFlagsBuf();
  42. @@ -477,9 +482,9 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
  43. const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
  44. {
  45. try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
  46. - catch(const CInBufferException &e) { return e.ErrorCode; }
  47. - catch(const CLzOutWindowException &e) { return e.ErrorCode; }
  48. - catch(...) { return S_FALSE; }
  49. + catch(const CInBufferException &e) { _errorMode = true; return e.ErrorCode; }
  50. + catch(const CLzOutWindowException &e) { _errorMode = true; return e.ErrorCode; }
  51. + catch(...) { _errorMode = true; return S_FALSE; }
  52. }
  53. STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
  54. diff --git a/CPP/7zip/Compress/Rar1Decoder.h b/CPP/7zip/Compress/Rar1Decoder.h
  55. index 630f089..01b606b 100644
  56. --- a/CPP/7zip/Compress/Rar1Decoder.h
  57. +++ b/CPP/7zip/Compress/Rar1Decoder.h
  58. @@ -39,6 +39,7 @@ public:
  59. Int64 m_UnpackSize;
  60. bool m_IsSolid;
  61. + bool _errorMode;
  62. UInt32 ReadBits(int numBits);
  63. HRESULT CopyBlock(UInt32 distance, UInt32 len);
  64. diff --git a/CPP/7zip/Compress/Rar2Decoder.cpp b/CPP/7zip/Compress/Rar2Decoder.cpp
  65. index b3f2b4b..0580c8d 100644
  66. --- a/CPP/7zip/Compress/Rar2Decoder.cpp
  67. +++ b/CPP/7zip/Compress/Rar2Decoder.cpp
  68. @@ -80,7 +80,8 @@ static const UInt32 kHistorySize = 1 << 20;
  69. static const UInt32 kWindowReservSize = (1 << 22) + 256;
  70. CDecoder::CDecoder():
  71. - m_IsSolid(false)
  72. + m_IsSolid(false),
  73. + m_TablesOK(false)
  74. {
  75. }
  76. @@ -100,6 +101,8 @@ UInt32 CDecoder::ReadBits(unsigned numBits) { return m_InBitStream.ReadBits(numB
  77. bool CDecoder::ReadTables(void)
  78. {
  79. + m_TablesOK = false;
  80. +
  81. Byte levelLevels[kLevelTableSize];
  82. Byte newLevels[kMaxTableSize];
  83. m_AudioMode = (ReadBits(1) == 1);
  84. @@ -170,6 +173,8 @@ bool CDecoder::ReadTables(void)
  85. }
  86. memcpy(m_LastLevels, newLevels, kMaxTableSize);
  87. + m_TablesOK = true;
  88. +
  89. return true;
  90. }
  91. @@ -344,6 +349,9 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
  92. return S_FALSE;
  93. }
  94. + if (!m_TablesOK)
  95. + return S_FALSE;
  96. +
  97. UInt64 startPos = m_OutWindowStream.GetProcessedSize();
  98. while (pos < unPackSize)
  99. {
  100. diff --git a/CPP/7zip/Compress/Rar2Decoder.h b/CPP/7zip/Compress/Rar2Decoder.h
  101. index 3a0535c..0e9005f 100644
  102. --- a/CPP/7zip/Compress/Rar2Decoder.h
  103. +++ b/CPP/7zip/Compress/Rar2Decoder.h
  104. @@ -139,6 +139,7 @@ class CDecoder :
  105. UInt64 m_PackSize;
  106. bool m_IsSolid;
  107. + bool m_TablesOK;
  108. void InitStructures();
  109. UInt32 ReadBits(unsigned numBits);
  110. diff --git a/CPP/7zip/Compress/Rar3Decoder.cpp b/CPP/7zip/Compress/Rar3Decoder.cpp
  111. index 3bf2513..6cb8a6a 100644
  112. --- a/CPP/7zip/Compress/Rar3Decoder.cpp
  113. +++ b/CPP/7zip/Compress/Rar3Decoder.cpp
  114. @@ -92,7 +92,8 @@ CDecoder::CDecoder():
  115. _writtenFileSize(0),
  116. _vmData(0),
  117. _vmCode(0),
  118. - m_IsSolid(false)
  119. + m_IsSolid(false),
  120. + _errorMode(false)
  121. {
  122. Ppmd7_Construct(&_ppmd);
  123. }
  124. @@ -545,6 +546,9 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing)
  125. return InitPPM();
  126. }
  127. + TablesRead = false;
  128. + TablesOK = false;
  129. +
  130. _lzMode = true;
  131. PrevAlignBits = 0;
  132. PrevAlignCount = 0;
  133. @@ -606,6 +610,9 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing)
  134. }
  135. }
  136. }
  137. + if (InputEofError())
  138. + return S_FALSE;
  139. +
  140. TablesRead = true;
  141. // original code has check here:
  142. @@ -623,6 +630,9 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing)
  143. RIF(m_LenDecoder.Build(&newLevels[kMainTableSize + kDistTableSize + kAlignTableSize]));
  144. memcpy(m_LastLevels, newLevels, kTablesSizesSum);
  145. +
  146. + TablesOK = true;
  147. +
  148. return S_OK;
  149. }
  150. @@ -824,7 +834,12 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress)
  151. PpmEscChar = 2;
  152. PpmError = true;
  153. InitFilters();
  154. + _errorMode = false;
  155. }
  156. +
  157. + if (_errorMode)
  158. + return S_FALSE;
  159. +
  160. if (!m_IsSolid || !TablesRead)
  161. {
  162. bool keepDecompressing;
  163. @@ -838,6 +853,8 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress)
  164. bool keepDecompressing;
  165. if (_lzMode)
  166. {
  167. + if (!TablesOK)
  168. + return S_FALSE;
  169. RINOK(DecodeLZ(keepDecompressing))
  170. }
  171. else
  172. @@ -901,8 +918,8 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
  173. _unpackSize = outSize ? *outSize : (UInt64)(Int64)-1;
  174. return CodeReal(progress);
  175. }
  176. - catch(const CInBufferException &e) { return e.ErrorCode; }
  177. - catch(...) { return S_FALSE; }
  178. + catch(const CInBufferException &e) { _errorMode = true; return e.ErrorCode; }
  179. + catch(...) { _errorMode = true; return S_FALSE; }
  180. // CNewException is possible here. But probably CNewException is caused
  181. // by error in data stream.
  182. }
  183. diff --git a/CPP/7zip/Compress/Rar3Decoder.h b/CPP/7zip/Compress/Rar3Decoder.h
  184. index c130cec..2f72d7d 100644
  185. --- a/CPP/7zip/Compress/Rar3Decoder.h
  186. +++ b/CPP/7zip/Compress/Rar3Decoder.h
  187. @@ -192,6 +192,7 @@ class CDecoder:
  188. UInt32 _lastFilter;
  189. bool m_IsSolid;
  190. + bool _errorMode;
  191. bool _lzMode;
  192. bool _unsupportedFilter;
  193. @@ -200,6 +201,7 @@ class CDecoder:
  194. UInt32 PrevAlignCount;
  195. bool TablesRead;
  196. + bool TablesOK;
  197. CPpmd7 _ppmd;
  198. int PpmEscChar;