Bug 1035592 (CVE-2017-8053) - VUL-1: CVE-2017-8053: podofo: denial of service via a crafted PDF file in PoDoFo::PdfParser::ReadDocumentStructure (PdfParser.cpp)
Summary: VUL-1: CVE-2017-8053: podofo: denial of service via a crafted PDF file in PoD...
Status: RESOLVED FIXED
Alias: CVE-2017-8053
Product: SUSE Security Incidents
Classification: Novell Products
Component: Incidents (show other bugs)
Version: unspecified
Hardware: Other Other
: P4 - Low : Normal
Target Milestone: unspecified
Assignee: Antonio Larrosa
QA Contact: Security Team bot
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-04-22 23:34 UTC by Mikhail Kasimov
Modified: 2019-10-31 08:17 UTC (History)
2 users (show)

See Also:
Found By: ---
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments
crash_CVE-2017-8053 (13.57 KB, application/pdf)
2017-04-22 23:34 UTC, Mikhail Kasimov
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Mikhail Kasimov 2017-04-22 23:34:58 UTC
Created attachment 722244 [details]
crash_CVE-2017-8053

Ref: https://nvd.nist.gov/vuln/detail/CVE-2017-8053
===================================================
Description

PoDoFo 0.9.5 allows denial of service (infinite recursion and stack consumption) via a crafted PDF file in PoDoFo::PdfParser::ReadDocumentStructure (PdfParser.cpp).

Source:  MITRE      Last Modified:  04/22/2017
===================================================

Hyperlink

[1] http://openwall.com/lists/oss-security/2017/04/22/1

[2] http://www.evernote.com/l/AnGe5jS_MvNDaZvZW-fzvV37H4ggSf5IkQo/

[2]:
================================================================================================
There is a infinite recursion in PoDoFo::PdfParser::ReadDocumentStructure(PdfParser.cpp )
In the ReadDocumentStructure function, it calls ReadXRefContents several time, for exmple in the end of ReadDocumentStructure:. 
    try {
        ReadXRefContents( m_nXRefOffset );
    } catch( PdfError & e ) {
        e.AddToCallstack( __FILE__, __LINE__, "Unable to load xref entries." );
        throw e;
    }

The ReadXRefContents and ReadXRefStreamContents will call each other if it meet some conditions. Just as below.

void PdfParser::ReadXRefStreamContents( pdf_long lOffset, bool bReadOnlyTrailer )
{
    m_device.Device()->Seek( lOffset );
    //....
    if(xrefObject.HasPrevious()) 
    {
        try {
            m_nIncrementalUpdates++;

            // PDFs that have been through multiple PDF tools may have a mix of xref tables (ISO 32000-1 7.5.4) 
            // and XRefStm streams (ISO 32000-1 7.5.8.1) and in the Prev chain, 
            // so call ReadXRefContents (which deals with both) instead of ReadXRefStreamContents 
            ReadXRefContents( xrefObject.GetPreviousOffset(), bReadOnlyTrailer );
        } catch(PdfError &e) {
            //....
        }
    }
}

void PdfParser::ReadXRefContents( pdf_long lOffset, bool bPositionAtEnd )
{
    pdf_int64 nFirstObject = 0;
    pdf_int64 nNumObjects  = 0;

    if( !this->IsNextToken( "xref" ) )
    {
//      if( m_ePdfVersion < ePdfVersion_1_5 )
//        Ulrich Arnold 19.10.2009, found linearized 1.3-pdf's with trailer-info in xref-stream
        if( m_ePdfVersion < ePdfVersion_1_3 )
        {
            PODOFO_RAISE_ERROR( ePdfError_NoXRef );
        }
        else
        {
            ReadXRefStreamContents( lOffset, bPositionAtEnd );
            return;
        }
    }

The crash log is just as follows:

./podofofuzzer: Running 1 inputs 1 time(s) each.
Running: crash-5aac275479284034b46368c836564266b0ed3694
ASAN:DEADLYSIGNAL
=================================================================
==30073==ERROR: AddressSanitizer: stack-overflow on address 0x7ffc70e74f18 (pc 0x0000004e6119 bp 0x7ffc70e75790 sp 0x7ffc70e74f20 T0)
    #0 0x4e6118  (/home/name/FUZZ-WORKSPACE/podofofuzzer+0x4e6118)
    #1 0x8a75c1  (/home/name/FUZZ-WORKSPACE/podofofuzzer+0x8a75c1)
    #2 0x4e6efc  (/home/name/FUZZ-WORKSPACE/podofofuzzer+0x4e6efc)
    #3 0x7fdbbe094277  (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0x121277)
    #4 0x61085e  (/home/name/FUZZ-WORKSPACE/podofofuzzer+0x61085e)

when debugging with gdb and checking the stack backtrace, it showed the program runs out of the stack as below :

#6884 0x000000000063a434 in PoDoFo::PdfParser::ReadXRefStreamContents (this=0x617000000080, lOffset=5923, bReadOnlyTrailer=false)
    at /home/name/podofo-0.9.5/src/base/PdfParser.cpp:875
#6885 0x000000000063438c in PoDoFo::PdfParser::ReadXRefContents (this=0x617000000080, lOffset=5923, bPositionAtEnd=false) at /home/name/podofo-0.9.5/src/base/PdfParser.cpp:682
#6886 0x000000000063a434 in PoDoFo::PdfParser::ReadXRefStreamContents (this=0x617000000080, lOffset=5923, bReadOnlyTrailer=false)
    at /home/name/podofo-0.9.5/src/base/PdfParser.cpp:875
#6887 0x000000000063438c in PoDoFo::PdfParser::ReadXRefContents (this=0x617000000080, lOffset=5923, bPositionAtEnd=false) at /home/name/podofo-0.9.5/src/base/PdfParser.cpp:682
#6888 0x000000000063a434 in PoDoFo::PdfParser::ReadXRefStreamContents (this=0x617000000080, lOffset=5923, bReadOnlyTrailer=false)
    at /home/name/podofo-0.9.5/src/base/PdfParser.cpp:875
#6889 0x000000000063438c in PoDoFo::PdfParser::ReadXRefContents (this=0x617000000080, lOffset=5923, bPositionAtEnd=false) at /home/name/podofo-0.9.5/src/base/PdfParser.cpp:682
#6890 0x000000000063a434 in PoDoFo::PdfParser::ReadXRefStreamContents (this=0x617000000080, lOffset=5923, bReadOnlyTrailer=false)
    at /home/name/podofo-0.9.5/src/base/PdfParser.cpp:875
#6891 0x000000000063438c in PoDoFo::PdfParser::ReadXRefContents (this=0x617000000080, lOffset=5923, bPositionAtEnd=false) at /home/name/podofo-0.9.5/src/base/PdfParser.cpp:682
#6892 0x000000000063a434 in PoDoFo::PdfParser::ReadXRefStreamContents (this=0x617000000080, lOffset=116, bReadOnlyTrailer=false)
    at /home/name/podofo-0.9.5/src/base/PdfParser.cpp:875
#6893 0x000000000063438c in PoDoFo::PdfParser::ReadXRefContents (this=0x617000000080, lOffset=116, bPositionAtEnd=false) at /home/name/podofo-0.9.5/src/base/PdfParser.cpp:682
#6894 0x00000000006303bf in PoDoFo::PdfParser::ReadDocumentStructure (this=0x617000000080) at /home/name/podofo-0.9.5/src/base/PdfParser.cpp:337
#6895 0x000000000062e252 in PoDoFo::PdfParser::ParseFile (this=0x617000000080, rDevice=..., bLoadOnDemand=true) at /home/name/podofo-0.9.5/src/base/PdfParser.cpp:220
#6896 0x000000000062ce49 in PoDoFo::PdfParser::ParseFile (this=0x617000000080, pszFilename=0x8ca380 <.str> "tempinput.pdf", bLoadOnDemand=true)
    at /home/name/podofo-0.9.5/src/base/PdfParser.cpp:164
#6897 0x00000000005cdc65 in PoDoFo::PdfMemDocument::Load (this=0x7fffffffbfe0, pszFilename=0x8ca380 <.str> "tempinput.pdf", bForUpdate=false)
    at /home/name/podofo-0.9.5/src/doc/PdfMemDocument.cpp:256
#6898 0x00000000005cd682 in PoDoFo::PdfMemDocument::PdfMemDocument (this=0x7fffffffbfe0, pszFilename=0x8ca380 <.str> "tempinput.pdf", bForUpdate=false)
    at /home/name/podofo-0.9.5/src/doc/PdfMemDocument.cpp:102

Thus,causing stack overflow.
============================================================================================


(open-)SUSE: https://software.opensuse.org/package/podofo

0.9.4 (TW, official repo)
0.9.3 (42.{1,2}, official repo)
Comment 2 Marcus Meissner 2019-10-31 08:17:07 UTC
podofopdfinfo crash-5aac275479284034b46368c836564266b0ed3694

no more infinite loop in 0.9.6, so all fixed I would say.