Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Alexander_Naumov:SLE-12:Update
podofo.34526
r1925-Fix-uncontrolled-memory-allocation-in-the...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File r1925-Fix-uncontrolled-memory-allocation-in-the-PdfParser-ReadXRefSubsection-CVE-2018-5296.patch of Package podofo.34526
------------------------------------------------------------------------ r1925 | domseichter | 2018-04-30 21:21:55 +0200 (lun, 30 abr 2018) | 1 line FIXED: #6 based on the patch by Mark Rogers. Limit the maximum number of indirect objects by default to 2^23-1 as in the PDF reference Appendix C implementation limits Index: src/base/PdfParser.cpp =================================================================== --- src/base/PdfParser.cpp (revision 1924) +++ src/base/PdfParser.cpp (revision 1925) @@ -72,8 +72,10 @@ namespace PoDoFo { -long PdfParser::s_nMaxObjects = std::numeric_limits<long>::max(); - +const long nMaxNumIndirectObjects = (1L << 23) - 1L; +long PdfParser::s_nMaxObjects = nMaxNumIndirectObjects; + + # class PdfRecursionGuard # { # // RAII recursion guard ensures m_nRecursionDepth is always decremented PdfParser::PdfParser( PdfVecObjects* pVecObjects ) : PdfTokenizer(), m_vecObjects( pVecObjects ), m_bStrictParsing( false ) @@ -352,13 +354,10 @@ m_nNumObjects = 0; } - // allow caller to specify a max object count to avoid very slow load times on large documents - if (s_nMaxObjects != std::numeric_limits<long>::max() - && m_nNumObjects > s_nMaxObjects) - PODOFO_RAISE_ERROR_INFO( ePdfError_ValueOutOfRange, "m_nNumObjects is greater than m_nMaxObjects." ); - if (m_nNumObjects > 0) - m_offsets.resize(m_nNumObjects); + { + ResizeOffsets( m_nNumObjects ); + } if( m_pLinearization ) { @@ -769,7 +768,7 @@ if( e == ePdfError_NoNumber || e == ePdfError_InvalidXRef || e == ePdfError_UnexpectedEOF ) break; else - { + { e.AddToCallstack( __FILE__, __LINE__ ); throw e; } @@ -820,19 +819,22 @@ } if ( static_cast<pdf_uint64>( nFirstObject ) + static_cast<pdf_uint64>( nNumObjects ) > static_cast<pdf_uint64>( std::numeric_limits<size_t>::max() ) ) + { PODOFO_RAISE_ERROR_INFO( ePdfError_ValueOutOfRange, "xref subsection's given entry numbers together too large" ); - + } + if( nFirstObject + nNumObjects > m_nNumObjects ) { try { + #ifdef _WIN32 - m_nNumObjects = static_cast<long>(nFirstObject + nNumObjects); - m_offsets.resize(static_cast<long>(nFirstObject+nNumObjects)); + m_nNumObjects = static_cast<long>(nFirstObject+nNumObjects); #else m_nNumObjects = nFirstObject + nNumObjects; - m_offsets.resize(nFirstObject+nNumObjects); #endif // _WIN32 + ResizeOffsets(nFirstObject + nNumObjects); + } catch (std::exception &) { // If m_nNumObjects*sizeof(TXRefEntry) > std::numeric_limits<size_t>::max() then // resize() throws std::length_error, for smaller allocations that fail it may throw @@ -1444,6 +1446,17 @@ } +void PdfParser::ResizeOffsets( pdf_long nNewSize ) +{ + // allow caller to specify a max object count to avoid very slow load times on large documents + if (nNewSize > s_nMaxObjects) + { + PODOFO_RAISE_ERROR_INFO( ePdfError_ValueOutOfRange, "nNewSize is greater than m_nMaxObjects." ); + } + + m_offsets.resize( nNewSize ); +} + void PdfParser::CheckEOFMarker() { // Check for the existence of the EOF marker Index: src/base/PdfParser.h =================================================================== --- src/base/PdfParser.h (revision 1924) +++ src/base/PdfParser.h (revision 1925) @@ -381,8 +381,7 @@ inline void SetIgnoreBrokenObjects( bool bBroken ); /** - * \return maximum object count to read (default is LONG_MAX - * which means no limit) + * \return maximum object count to read */ inline static long GetMaxObjectCount(); @@ -394,6 +393,10 @@ * working set and spend 15 mins in Load() before throwing * an out of memory exception. * + * By default, the maximum object count is set to 8388607 + * which is the maximum number of indirect objects according + * to the PDF specification. + * * \param nMaxObjects set max number of objects */ inline static void SetMaxObjectCount( long nMaxObjects ); @@ -564,6 +567,15 @@ */ void UpdateDocumentVersion(); + + /** Resize the internal structure m_offsets in a safe manner. + * The limit for the maximum number of indirect objects in a PDF file is checked by this method. + * The maximum is 2^23-1 (8.388.607). + * + * \param nNewSize new size of the vector + */ + void ResizeOffsets( pdf_long nNewSize ); + private: EPdfVersion m_ePdfVersion; #@@ -594,7 +606,7 @@ # int m_nRecursionDepth; # # static long s_nMaxObjects; #- #+ # std::set<pdf_long> m_visitedXRefOffsets; # }; # Index: test/unit/BasicTypeTest.cpp =================================================================== --- test/unit/BasicTypeTest.cpp (revision 1924) +++ test/unit/BasicTypeTest.cpp (revision 1925) @@ -40,3 +40,8 @@ { CPPUNIT_ASSERT_MESSAGE("pdf_uint64 is big enough to hold an xref entry", std::numeric_limits<pdf_uint64>::max() >= PODOFO_ULL_LITERAL(9999999999) ); } + +void BasicTypeTest::testDefaultMaximumNumberOfObjects() +{ + CPPUNIT_ASSERT_EQUAL_MESSAGE("PdfReference allows 8,388,607 indirect objects.", 8388607L, PdfParser::GetMaxObjectCount() ); +} Index: test/unit/BasicTypeTest.h =================================================================== --- test/unit/BasicTypeTest.h (revision 1924) +++ test/unit/BasicTypeTest.h (revision 1925) @@ -31,16 +31,18 @@ */ class BasicTypeTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE( BasicTypeTest ); - CPPUNIT_TEST( testXrefOffsetTypeSize ); - CPPUNIT_TEST_SUITE_END(); - + CPPUNIT_TEST_SUITE( BasicTypeTest ); + CPPUNIT_TEST( testXrefOffsetTypeSize ); + CPPUNIT_TEST( testDefaultMaximumNumberOfObjects ); + CPPUNIT_TEST_SUITE_END(); + public: - void setUp(); - void tearDown(); - - void testXrefOffsetTypeSize(); - + void setUp(); + void tearDown(); + + void testXrefOffsetTypeSize(); + void testDefaultMaximumNumberOfObjects(); + private: }; ------------------------------------------------------------------------
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor