From c3430f05c2d0be9a30b1a2bd1e4307f666f046fc Mon Sep 17 00:00:00 2001
From: Mark Rogers <mark.rogers@powermapper.com>
Date: Fri, 7 Apr 2017 15:16:18 +0100
Subject: [PATCH] PoDoFo: fix CVE-2017-5852 stack overflow in
 GetInheritedKeyFromObject

---
 Electrum/Mapper/Libs/podofo/src/doc/PdfPage.cpp | 16 ++++++++++++++--
 Electrum/Mapper/Libs/podofo/src/doc/PdfPage.h   |  2 +-
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/Electrum/Mapper/Libs/podofo/src/doc/PdfPage.cpp b/Electrum/Mapper/Libs/podofo/src/doc/PdfPage.cpp
index 8aab66f..66e817b 100644
--- a/Electrum/Mapper/Libs/podofo/src/doc/PdfPage.cpp
+++ b/Electrum/Mapper/Libs/podofo/src/doc/PdfPage.cpp
@@ -212,7 +212,7 @@ PdfRect PdfPage::CreateStandardPageSize( const EPdfPageSize ePageSize, bool bLan
     return rect;
 }
 
-const PdfObject* PdfPage::GetInheritedKeyFromObject( const char* inKey, const PdfObject* inObject ) const
+const PdfObject* PdfPage::GetInheritedKeyFromObject( const char* inKey, const PdfObject* inObject, int depth ) const
 {
     const PdfObject* pObj = NULL;
 
@@ -227,9 +227,21 @@ const PdfObject* PdfPage::GetInheritedKeyFromObject( const char* inKey, const Pd
     // if we get here, we need to go check the parent - if there is one!
     if( inObject->GetDictionary().HasKey( "Parent" ) ) 
     {
+        // CVE-2017-5852 - prevent stack overflow if Parent chain contains a loop, or is very long
+        // e.g. pObj->GetParent() == pObj or pObj->GetParent()->GetParent() == pObj
+        // default stack sizes
+        // Windows: 1 MB
+        // Linux: 2 MB
+        // macOS: 8 MB for main thread, 0.5 MB for secondary threads
+        // 0.5 MB is enough space for 1000 512 byte stack frames and 2000 256 byte stack frames
+        const int maxRecursionDepth = 1000;
+        
+        if ( depth > maxRecursionDepth )
+            PODOFO_RAISE_ERROR( ePdfError_ValueOutOfRange );
+        
         pObj = inObject->GetIndirectKey( "Parent" );
         if( pObj )
-            pObj = GetInheritedKeyFromObject( inKey, pObj );
+            pObj = GetInheritedKeyFromObject( inKey, pObj, depth+1 );
     }
 
     return pObj;
diff --git a/Electrum/Mapper/Libs/podofo/src/doc/PdfPage.h b/Electrum/Mapper/Libs/podofo/src/doc/PdfPage.h
index 855b2e4..3e9af91 100644
--- a/Electrum/Mapper/Libs/podofo/src/doc/PdfPage.h
+++ b/Electrum/Mapper/Libs/podofo/src/doc/PdfPage.h
@@ -291,7 +291,7 @@ class PODOFO_DOC_API PdfPage : public PdfElement, public PdfCanvas {
     /** Method for getting a key value that could be inherited (such as the boxes, resources, etc.)
      *  \returns PdfObject - the result of the key fetching or NULL
      */
-    const PdfObject* GetInheritedKeyFromObject( const char* inKey, const PdfObject* inObject ) const; 
+    const PdfObject* GetInheritedKeyFromObject( const char* inKey, const PdfObject* inObject, int depth = 0 ) const;
 
     /** Get the annotations array.
      *  \param bCreate if true the annotations array is created 
-- 
2.2.1

