CVE-2022-29777 (C++, published 2022-06-02T14:15Z)
Description: value: 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 v3 base score: 9.8)
Weakness: CWE-787 \u2014 Out-of-bounds Write
The product writes data past the end, or before the beginning, of the intended buffer.
Repository: https://github.com/ONLYOFFICE/core
Files changed:
DesktopEditor/fontengine/fontconverter/FontFileBase.h
DesktopEditor/fontengine/fontconverter/FontFileType1.cpp
Commit message: Fix 34, 35, 37


Vulnerable code:
            m_nLen = nLen;
            m_bFreeFileData = bFreeFileData;
        int          GetS8    (int nPos, bool *pbSuccess)
            if ( nPos < 0 || nPos >= m_nLen )
        int          GetU8    (int nPos, bool *pbSuccess)
            if ( nPos < 0 || nPos >= m_nLen )
        int          GetS16BE (int nPos, bool *pbSuccess)
            if ( nPos < 0 || nPos + 1 >= m_nLen )
        int          GetU16BE (int nPos, bool *pbSuccess)
            if ( nPos < 0 || nPos + 1 >= m_nLen)
        int          GetS32BE (int nPos, bool *pbSuccess)
            if ( nPos < 0 || nPos + 3 >= m_nLen )
        unsigned int GetU32BE (int nPos, bool *pbSuccess)
            if ( nPos < 0 || nPos + 3 >= m_nLen )
        unsigned int GetU32LE (int nPos, bool *pbSuccess)
            if ( nPos < 0 || nPos + 3 >= m_nLen )
        unsigned int GetUVarBE(int nPos, int nSize, bool *pbSuccess)
            if ( nPos < 0 || nPos + nSize > m_nLen )
        bool         CheckRegion(int nPos, int nSize)
            return (nPos >= 0 && nPos + nSize >= nPos && nPos + nSize <= m_nLen);
        int          Read(void* pDestBuffer, int nSize)
            if ( m_nPos + nSize >= m_nLen )
                nSize = m_nLen - m_nPos - 1;
        int            m_nLen;
        int            m_nPos;

                        while ( ( nChar = sEexec[++nIndex] ) != ' ' )
        int nBufLen = 0;

Fixed code:
            m_nLen = (nLen > 0) ? 0 : (unsigned int)nLen;
            m_bFreeFileData = bFreeFileData;            
        int          GetS8    (const unsigned int& nPos, bool *pbSuccess)
            if ( nPos >= m_nLen )
        int          GetU8    (const unsigned int& nPos, bool *pbSuccess)
            if ( nPos >= m_nLen )
        int          GetS16BE (const unsigned int& nPos, bool *pbSuccess)
            if ( m_nLen < 2 || nPos > (m_nLen - 2) )
        int          GetU16BE (const unsigned int& nPos, bool *pbSuccess)
            if ( m_nLen < 2 || nPos > (m_nLen - 2) )
        int          GetS32BE (const unsigned int& nPos, bool *pbSuccess)
            if ( m_nLen < 4 || nPos > (m_nLen - 4) )
        unsigned int GetU32BE (const unsigned int& nPos, bool *pbSuccess)
            if ( m_nLen < 4 || nPos > (m_nLen - 4) )
        unsigned int GetU32LE (const unsigned int& nPos, bool *pbSuccess)
            if ( m_nLen < 4 || nPos > (m_nLen - 4) )
        unsigned int GetUVarBE(const unsigned int& nPos, const unsigned int& nSize, bool *pbSuccess)
            if ( m_nLen < nSize || nPos > (m_nLen - nSize) )
        bool         CheckRegion(const unsigned int& nPos, const unsigned int& nSize)
            return (m_nLen >= nSize && nPos <= (m_nLen - nSize));
        int          Read(void* pDestBuffer, unsigned int nSize)
            if (m_nPos >= m_nLen)
                nSize = 0;
            else if (nSize > (m_nLen - m_nPos))
                nSize = m_nLen - m_nPos;
        unsigned int   m_nLen;
        unsigned int   m_nPos;
							if (nCode < 0) nCode = 0;								
                        while ( nIndex < nEexecLen && ( nChar = sEexec[++nIndex] ) != ' ' )
        unsigned int nBufLen = 0;