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

Generated by cgit