Bug#897674: p7zip-rar: CVE-2018-10115

2019-02-24 Thread Raphael Kubo da Costa

I was recently looking at this CVE and CVE 2018 10115.patch.

According to upstream 7-zip [1], this bug was fixed in version 18.05. In 
the upstream release announcement, someone asked about variables like 
_errorMode that were introduced earlier to deal with CVE-2018-5996 [2] 
and how they had been removed from this release.


The 7-Zip maintainer replied it was intentional and both CVEs should be 
fixed with that code. I've diff'ed 18.03 and 18.05, and _errorMode is 
either commented out or removed in the code, while the existing 
CVE_2018_10115.patch still has them in addition to the _solidAllowed 
stuff. I just package p7zip so I don't know much about how its 
implementation works, but I figured it'd be a better idea to make the 
CVE-2018-10115 patch more similar to what upstream had.


This new version is attached and follows what 18.05 upstream does.

[1] https://www.7-zip.org/history.txt
[2] 
https://sourceforge.net/p/sevenzip/discussion/45797/thread/adc65bfa/#8b13
--- CPP/7zip/Compress/Rar1Decoder.cpp.orig	2019-02-24 20:16:23.682521000 +0100
+++ CPP/7zip/Compress/Rar1Decoder.cpp	2019-02-24 22:02:59.461303000 +0100
@@ -29,7 +29,7 @@
 };
 */
 
-CDecoder::CDecoder(): m_IsSolid(false), _errorMode(false) { }
+CDecoder::CDecoder(): _isSolid(false), _solidAllowed(false) { }
 
 void CDecoder::InitStructures()
 {
@@ -345,7 +345,7 @@
 
 void CDecoder::InitData()
 {
-  if (!m_IsSolid)
+  if (!_isSolid)
   {
 AvrPlcB = AvrLn1 = AvrLn2 = AvrLn3 = NumHuf = Buf60 = 0;
 AvrPlc = 0x3500;
@@ -391,6 +391,11 @@
   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,22 +403,18 @@
 
   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();
 InitHuff();
   }
 
-  if (_errorMode)
-return S_FALSE;
-
   if (m_UnpackSize > 0)
   {
 GetFlagsBuf();
@@ -475,6 +476,7 @@
   }
   if (m_UnpackSize < 0)
 return S_FALSE;
+  _solidAllowed = true;
   return m_OutWindowStream.Flush();
 }
 
@@ -482,16 +484,16 @@
 const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
 {
   try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
-  catch(const CInBufferException ) { _errorMode = true; return e.ErrorCode; }
-  catch(const CLzOutWindowException ) { _errorMode = true; return e.ErrorCode; }
-  catch(...) { _errorMode = true; return S_FALSE; }
+  catch(const CInBufferException ) { return e.ErrorCode; }
+  catch(const CLzOutWindowException ) { return e.ErrorCode; }
+  catch(...) { return S_FALSE; }
 }
 
 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;
 }
 
--- CPP/7zip/Compress/Rar1Decoder.h.orig	2019-02-24 20:16:23.683118000 +0100
+++ CPP/7zip/Compress/Rar1Decoder.h	2019-02-24 22:01:21.915855000 +0100
@@ -38,8 +38,8 @@
   UInt32 LastLength;
 
   Int64 m_UnpackSize;
-  bool m_IsSolid;
-  bool _errorMode;
+  bool _isSolid;
+  bool _solidAllowed;
 
   UInt32 ReadBits(int numBits);
   HRESULT CopyBlock(UInt32 distance, UInt32 len);
--- CPP/7zip/Compress/Rar2Decoder.cpp.orig	2019-02-24 20:16:23.683974000 +0100
+++ CPP/7zip/Compress/Rar2Decoder.cpp	2019-02-24 20:16:23.691384000 +0100
@@ -80,7 +80,8 @@
 static const UInt32 kWindowReservSize = (1 << 22) + 256;
 
 CDecoder::CDecoder():
-  m_IsSolid(false),
+  _isSolid(false),
+  _solidAllowed(false),
   m_TablesOK(false)
 {
 }
@@ -320,6 +321,10 @@
   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 @@
   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 @@
   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 @@
 
   if (!ReadLastTables())
 return S_FALSE;
+
+  _solidAllowed = true;
+
   return 

Bug#897674: p7zip-rar: CVE-2018-10115

2018-05-04 Thread Salvatore Bonaccorso
Source: p7zip-rar
Version: 16.02-1
Severity: grave
Tags: security upstream

Hi,

The following vulnerability was published for p7zip-rar.

CVE-2018-10115[0]:
| Incorrect initialization logic of RAR decoder objects in 7-Zip 18.03
| and before can lead to usage of uninitialized memory, allowing remote
| attackers to cause a denial of service (segmentation fault) or execute
| arbitrary code via a crafted RAR archive.

If you fix the vulnerability please also make sure to include the
CVE (Common Vulnerabilities & Exposures) id in your changelog entry.

For further information see:

[0] https://security-tracker.debian.org/tracker/CVE-2018-10115
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-10115
[1] 
https://landave.io/2018/05/7-zip-from-uninitialized-memory-to-remote-code-execution/
[2] https://sourceforge.net/p/sevenzip/discussion/45797/thread/adc65bfa/

Please adjust the affected versions in the BTS as needed.

Regards,
Salvatore