CVE-2016-10327 (published 2017-04-14T04:59Z)

LibreOffice before 2016-12-22 has an out-of-bounds write caused by a heap-based buffer overflow related to the EnhWMFReader::ReadEnhWMF function in vcl/source/filter/wmf/enhwmf.cxx.

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.0/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/LibreOffice/core
commit_details: repo_url: https://github.com/LibreOffice/core
author: Caolán McNamara
author_date: 2016-12-22 13:35:31+00:00
msg: Resolves: ofz#313 cbBmiSrc > getDIBV5HeaderSize

Change-Id: I67fb67dc0a4cb609b8f1391c1eb6dd395755a933
repository: repo_url: https://github.com/LibreOffice/core
repo_name: LibreOffice/core
description: Read-only LibreOffice core repo - no pull request (use gerrit instead https://gerrit.libreoffice.org/) - don't download zip, use https://dev-www.libreoffice.org/bundles/  instead
repo_language: C++
owner: LibreOffice
file_changes: filename: enhwmf.cxx
change_type: ModificationType.MODIFY
diff: @@ -1252,13 +1252,22 @@ bool EnhWMFReader::ReadEnhWMF()
                     else
                     {
                         const sal_uInt32 nSourceSize = cbBmiSrc + cbBitsSrc + 14;
-                        if ( nSourceSize <= ( nEndPos - nStartPos ) )
+                        bool bSafeRead = nSourceSize <= (nEndPos - nStartPos);
+                        sal_uInt32 nDeltaToDIB5HeaderSize(0);
+                        const bool bReadAlpha(0x01 == aFunc.aAlphaFormat);
+                        if (bSafeRead && bReadAlpha)
                         {
                             // we need to read alpha channel data if AlphaFormat of BLENDFUNCTION is
                             // AC_SRC_ALPHA (==0x01). To read it, create a temp DIB-File which is ready
                             // for DIB-5 format
-                            const bool bReadAlpha(0x01 == aFunc.aAlphaFormat);
-                            const sal_uInt32 nDeltaToDIB5HeaderSize(bReadAlpha ? getDIBV5HeaderSize() - cbBmiSrc : 0);
+                            const sal_uInt32 nHeaderSize = getDIBV5HeaderSize();
+                            if (cbBmiSrc > nHeaderSize)
+                                bSafeRead = false;
+                            else
+                                nDeltaToDIB5HeaderSize = nHeaderSize - cbBmiSrc;
+                        }
+                        if (bSafeRead)
+                        {
                             const sal_uInt32 nTargetSize(cbBmiSrc + nDeltaToDIB5HeaderSize + cbBitsSrc + 14);
                             char* pBuf = new char[ nTargetSize ];
                             SvMemoryStream aTmp( pBuf, nTargetSize, StreamMode::READ | StreamMode::WRITE );
@@ -1277,7 +1286,7 @@ bool EnhWMFReader::ReadEnhWMF()
                             pWMF->Seek( nStart + offBmiSrc );
                             pWMF->ReadBytes(pBuf + 14, cbBmiSrc);
 
-                            if(bReadAlpha)
+                            if (bReadAlpha)
                             {
                                 // need to add values for all stuff that DIBV5Header is bigger
                                 // than DIBInfoHeader, all values are correctly initialized to zero,

programming_language: Batchfile