CVE-2022-29777 (published 2022-06-02T14:15Z)

Onlyoffice Document Server v6.0.0 and below and Core 6.1.0.26 and below were discovered to contain a heap overflow via the component DesktopEditor/fontengine/fontconverter/FontFileBase.h.

Severity: HIGH
CVSS v2 base score: 7.5 (AV:N/AC:L/Au:N/C:P/I:P/A:P)
CVSS v3 base score: 9.8, CRITICAL (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-787
cwe_name: Out-of-bounds Write
description: The product writes data past the end, or before the beginning, of the intended buffer.
extended_description: 
            
            
             
			 
         
         

Fix information:
repo_url: https://github.com/ONLYOFFICE/core
commit_details: repo_url: https://github.com/ONLYOFFICE/core
author: Oleg Korshul
author_date: 2020-09-30 13:52:41+03:00
msg: Fix 34, 35, 37
repository: repo_url: https://github.com/ONLYOFFICE/core
repo_name: ONLYOFFICE/core
description: Server core components which are a part of ONLYOFFICE Document Server
repo_language: C++
owner: ONLYOFFICE
file_changes: filename: FontFileBase.h
change_type: ModificationType.MODIFY
diff: @@ -61,9 +61,9 @@ namespace NSFontConverter
         CFontFileBase(char *sFile, int nLen, bool bFreeFileData)
         {
             m_sFileData = m_sFile = (unsigned char *)sFile;
-            m_nLen = nLen;
-            m_bFreeFileData = bFreeFileData;
+            m_nLen = (nLen > 0) ? 0 : (unsigned int)nLen;
             m_nPos = 0;
+            m_bFreeFileData = bFreeFileData;            
         }
 
         void         Reset()
@@ -94,11 +94,11 @@ namespace NSFontConverter
         // S = signed / U = unsigned
         // 8/16/32/Var = word length, in bytes
         // BE = big endian
-        int          GetS8    (int nPos, bool *pbSuccess)
+        int          GetS8    (const unsigned int& nPos, bool *pbSuccess)
         {
             //*pbSuccess = true;
 
-            if ( nPos < 0 || nPos >= m_nLen )
+            if ( nPos >= m_nLen )
             {
                 *pbSuccess = false;
                 return 0;
@@ -109,10 +109,10 @@ namespace NSFontConverter
             return nRes;
         }
 
-        int          GetU8    (int nPos, bool *pbSuccess)
+        int          GetU8    (const unsigned int& nPos, bool *pbSuccess)
         {
             //*pbSuccess = true;
-            if ( nPos < 0 || nPos >= m_nLen )
+            if ( nPos >= m_nLen )
             {
                 *pbSuccess = false;
                 return 0;
@@ -120,11 +120,11 @@ namespace NSFontConverter
             return m_sFile[ nPos ];
         }
 
-        int          GetS16BE (int nPos, bool *pbSuccess)
+        int          GetS16BE (const unsigned int& nPos, bool *pbSuccess)
         {
             //*pbSuccess = true;
 
-            if ( nPos < 0 || nPos + 1 >= m_nLen )
+            if ( m_nLen < 2 || nPos > (m_nLen - 2) )
             {
                 *pbSuccess = false;
                 return 0;
@@ -136,11 +136,11 @@ namespace NSFontConverter
             return nRes;
         }
 
-        int          GetU16BE (int nPos, bool *pbSuccess)
+        int          GetU16BE (const unsigned int& nPos, bool *pbSuccess)
         {
             //*pbSuccess = true;
 
-            if ( nPos < 0 || nPos + 1 >= m_nLen)
+            if ( m_nLen < 2 || nPos > (m_nLen - 2) )
             {
                 *pbSuccess = false;
                 return 0;
@@ -150,11 +150,11 @@ namespace NSFontConverter
             return nRes;
         }
 
-        int          GetS32BE (int nPos, bool *pbSuccess)
+        int          GetS32BE (const unsigned int& nPos, bool *pbSuccess)
         {
             //*pbSuccess = true;
 
-            if ( nPos < 0 || nPos + 3 >= m_nLen )
+            if ( m_nLen < 4 || nPos > (m_nLen - 4) )
             {
                 *pbSuccess = false;
                 return 0;
@@ -169,11 +169,11 @@ namespace NSFontConverter
             return nRes;
         }
 
-        unsigned int GetU32BE (int nPos, bool *pbSuccess)
+        unsigned int GetU32BE (const unsigned int& nPos, bool *pbSuccess)
         {
             //*pbSuccess = true;
 
-            if ( nPos < 0 || nPos + 3 >= m_nLen )
+            if ( m_nLen < 4 || nPos > (m_nLen - 4) )
             {
                 *pbSuccess = false;
                 return 0;
@@ -184,11 +184,11 @@ namespace NSFontConverter
             nRes = (nRes << 8) + m_sFile[nPos + 3];
             return nRes;
         }
-        unsigned int GetU32LE (int nPos, bool *pbSuccess)
+        unsigned int GetU32LE (const unsigned int& nPos, bool *pbSuccess)
         {
             //*pbSuccess = true;
 
-            if ( nPos < 0 || nPos + 3 >= m_nLen )
+            if ( m_nLen < 4 || nPos > (m_nLen - 4) )
             {
                 *pbSuccess = false;
                 return 0;
@@ -199,11 +199,11 @@ namespace NSFontConverter
             nRes = (nRes << 8) + m_sFile[nPos + 0];
             return nRes;
         }
-        unsigned int GetUVarBE(int nPos, int nSize, bool *pbSuccess)
+        unsigned int GetUVarBE(const unsigned int& nPos, const unsigned int& nSize, bool *pbSuccess)
         {
             //*pbSuccess = true;
 
-            if ( nPos < 0 || nPos + nSize > m_nLen )
+            if ( m_nLen < nSize || nPos > (m_nLen - nSize) )
             {
                 *pbSuccess = false;
                 return 0;
@@ -215,9 +215,9 @@ namespace NSFontConverter
             return nRes;
         }
 
-        bool         CheckRegion(int nPos, int nSize)
+        bool         CheckRegion(const unsigned int& nPos, const unsigned int& nSize)
         {
-            return (nPos >= 0 && nPos + nSize >= nPos && nPos + nSize <= m_nLen);
+            return (m_nLen >= nSize && nPos <= (m_nLen - nSize));
         }
         int          ReadS8   (bool *pbSuccess)
         {
@@ -239,10 +239,12 @@ namespace NSFontConverter
             m_nPos += 4;
             return unResult;
         }
-        int          Read(void* pDestBuffer, int nSize)
+        int          Read(void* pDestBuffer, unsigned int nSize)
         {
-            if ( m_nPos + nSize >= m_nLen )
-                nSize = m_nLen - m_nPos - 1;
+            if (m_nPos >= m_nLen)
+                nSize = 0;
+            else if (nSize > (m_nLen - m_nPos))
+                nSize = m_nLen - m_nPos;
 
             memcpy( pDestBuffer, (m_sFile + m_nPos), nSize );
             m_nPos += nSize;
@@ -254,10 +256,9 @@ namespace NSFontConverter
 
         unsigned char *m_sFileData;
         unsigned char *m_sFile;
-        int            m_nLen;
+        unsigned int   m_nLen;
+        unsigned int   m_nPos;
         bool           m_bFreeFileData;
-        int            m_nPos;
-
     };
 }
 

programming_language: C++
filename: FontFileType1.cpp
change_type: ModificationType.MODIFY
diff: @@ -397,6 +397,7 @@ namespace NSFontConverter
                             char nChar = *pTemp;
                             *pTemp = '\0';
                             nCode = atoi( pCur );
+							if (nCode < 0) nCode = 0;								
                             *pTemp = nChar;
                             if ( nCode == 8 && *pTemp == '#')
                             {
@@ -612,7 +613,7 @@ namespace NSFontConverter
                         sToken.clear();
                         sGlyph.clear();
 
-                        while ( ( nChar = sEexec[++nIndex] ) != ' ' )
+                        while ( nIndex < nEexecLen && ( nChar = sEexec[++nIndex] ) != ' ' )
                             sGlyph.push_back( (wchar_t)nChar );
                     }
                 }
@@ -656,7 +657,7 @@ namespace NSFontConverter
         int nChar = 0;
 
         unsigned char *sBuffer = NULL;
-        int nBufLen = 0;
+        unsigned int nBufLen = 0;
 
         while ( nBlockType != PFB_DONE )
         {

programming_language: C++