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

LibreOffice before 2017-01-02 has an out-of-bounds write caused by a heap-based buffer overflow related to the tools::Polygon::Insert function in tools/source/generic/poly.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: 2017-01-02 11:53:31+00:00
msg: ofz#372 check if ImplSplit succeeded

Change-Id: I1e34295fe3ee5f77e787f583616d52fa92a0eca4
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: poly.h
change_type: ModificationType.MODIFY
diff: @@ -43,7 +43,7 @@ public:
 
     void            ImplSetSize( sal_uInt16 nSize, bool bResize = true );
     void            ImplCreateFlagArray();
-    void            ImplSplit( sal_uInt16 nPos, sal_uInt16 nSpace, ImplPolygon const * pInitPoly = nullptr );
+    bool            ImplSplit( sal_uInt16 nPos, sal_uInt16 nSpace, ImplPolygon const * pInitPoly = nullptr );
 };
 
 #define MAX_POLYGONS        ((sal_uInt16)0x3FF0)

programming_language: C++
filename: poly.cxx
change_type: ModificationType.MODIFY
diff: @@ -212,11 +212,14 @@ void ImplPolygon::ImplSetSize( sal_uInt16 nNewSize, bool bResize )
     mnPoints   = nNewSize;
 }
 
-void ImplPolygon::ImplSplit( sal_uInt16 nPos, sal_uInt16 nSpace, ImplPolygon const * pInitPoly )
+bool ImplPolygon::ImplSplit( sal_uInt16 nPos, sal_uInt16 nSpace, ImplPolygon const * pInitPoly )
 {
     //Can't fit this in :-(, throw ?
     if (mnPoints + nSpace > USHRT_MAX)
-        return;
+    {
+        SAL_WARN("tools", "Polygon needs " << mnPoints + nSpace << " points, but only " << USHRT_MAX << " possible");
+        return false;
+    }
 
     const sal_uInt16    nNewSize = mnPoints + nSpace;
     const std::size_t   nSpaceSize = static_cast<std::size_t>(nSpace) * sizeof(Point);
@@ -272,6 +275,8 @@ void ImplPolygon::ImplSplit( sal_uInt16 nPos, sal_uInt16 nSpace, ImplPolygon con
         mpPointAry = pNewAry;
         mnPoints   = nNewSize;
     }
+
+    return true;
 }
 
 void ImplPolygon::ImplCreateFlagArray()
@@ -1472,8 +1477,8 @@ void Polygon::Insert( sal_uInt16 nPos, const Point& rPt )
     if( nPos >= mpImplPolygon->mnPoints )
         nPos = mpImplPolygon->mnPoints;
 
-    mpImplPolygon->ImplSplit( nPos, 1 );
-    mpImplPolygon->mpPointAry[ nPos ] = rPt;
+    if (mpImplPolygon->ImplSplit(nPos, 1))
+        mpImplPolygon->mpPointAry[ nPos ] = rPt;
 }
 
 void Polygon::Insert( sal_uInt16 nPos, const tools::Polygon& rPoly )

programming_language: C++