Bug 44660

Summary: Stack overflow in libpoppler in PDFDoc::markObject()
Product: poppler Reporter: Arseny Solokha <asolokha>
Component: generalAssignee: poppler-bugs <poppler-bugs>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: medium CC: Thomas.Freitag
Version: unspecified   
Hardware: x86-64 (AMD64)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:
Attachments: gdb backtrace
breaks endless loop in markObject

Description Arseny Solokha 2012-01-10 20:10:41 UTC
Created attachment 55404 [details]
gdb backtrace

pdfunite exposes a stack overflow in libpoppler w/ certain files (backtrace attached). The crash is reproducible w/ either pdfunite 0.18.2 or built from today's git (master).

Steps to reproduce:
% wget http://svnbook.red-bean.com/en/1.7/svn-book.pdf
% mv svn-book.pdf a.pdf
% cp a.pdf b.pdf
% pdfunite svn-book.pdf b.pdf c.pdf

% valgrind pdfunite a.pdf b.pdf c.pdf
==31239== Memcheck, a memory error detector
==31239== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==31239== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==31239== Command: pdfunite a.pdf b.pdf c.pdf
==31239== 
==31239== Stack overflow in thread 1: can't grow stack to 0x7fe801ff8
==31239== 
==31239== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==31239==  Access not within mapped region at address 0x7FE801FF8
==31239==    at 0x4F4E9FF: Lexer::getChar(bool) (in /usr/lib64/libpoppler.so.19.0.0)
==31239==  If you believe this happened as a result of a stack
==31239==  overflow in your program's main thread (unlikely but
==31239==  possible), you can try to increase the size of the
==31239==  main thread stack using the --main-stacksize= flag.
==31239==  The main thread stack size used in this run was 8388608.
==31239== Stack overflow in thread 1: can't grow stack to 0x7fe801ff0
==31239== 
==31239== Process terminating with default action of signal 11 (SIGSEGV)
==31239==  Access not within mapped region at address 0x7FE801FF0
==31239==    at 0x4A25670: _vgnU_freeres (in /usr/lib64/valgrind/vgpreload_core-amd64-linux.so)
==31239==  If you believe this happened as a result of a stack
==31239==  overflow in your program's main thread (unlikely but
==31239==  possible), you can try to increase the size of the
==31239==  main thread stack using the --main-stacksize= flag.
==31239==  The main thread stack size used in this run was 8388608.
==31239== 
==31239== HEAP SUMMARY:
==31239==     in use at exit: 94,978,141 bytes in 89,540 blocks
==31239==   total heap usage: 5,528,951 allocs, 5,439,411 frees, 207,618,968 bytes allocated
==31239== 
==31239== LEAK SUMMARY:
==31239==    definitely lost: 548 bytes in 32 blocks
==31239==    indirectly lost: 512 bytes in 4 blocks
==31239==      possibly lost: 0 bytes in 0 blocks
==31239==    still reachable: 94,977,081 bytes in 89,504 blocks
==31239==         suppressed: 0 bytes in 0 blocks
==31239== Rerun with --leak-check=full to see details of leaked memory
==31239== 
==31239== For counts of detected and suppressed errors, rerun with: -v
==31239== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)
% valgrind --main-stacksize=16777216 pdfunite a.pdf b.pdf c.pdf      
==880== Memcheck, a memory error detector                                         
==880== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==880== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==880== Command: pdfunite a.pdf b.pdf c.pdf
==880== 
==880== Stack overflow in thread 1: can't grow stack to 0x7fe001fc0
==880== 
==880== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==880==  Access not within mapped region at address 0x7FE001FC0
==880==    at 0x4C2B48B: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==880==  If you believe this happened as a result of a stack
==880==  overflow in your program's main thread (unlikely but
==880==  possible), you can try to increase the size of the
==880==  main thread stack using the --main-stacksize= flag.
==880==  The main thread stack size used in this run was 16777216.
==880== Stack overflow in thread 1: can't grow stack to 0x7fe001fb8
==880== 
==880== Process terminating with default action of signal 11 (SIGSEGV)
==880==  Access not within mapped region at address 0x7FE001FB8
==880==    at 0x4A25670: _vgnU_freeres (in /usr/lib64/valgrind/vgpreload_core-amd64-linux.so)
==880==  If you believe this happened as a result of a stack
==880==  overflow in your program's main thread (unlikely but
==880==  possible), you can try to increase the size of the
==880==  main thread stack using the --main-stacksize= flag.
==880==  The main thread stack size used in this run was 16777216.
==880== 
==880== HEAP SUMMARY:
==880==     in use at exit: 189,550,428 bytes in 178,782 blocks
==880==   total heap usage: 11,050,679 allocs, 10,871,897 frees, 412,291,111 bytes allocated
==880== 
==880== LEAK SUMMARY:
==880==    definitely lost: 548 bytes in 32 blocks
==880==    indirectly lost: 512 bytes in 4 blocks
==880==      possibly lost: 0 bytes in 0 blocks
==880==    still reachable: 189,549,368 bytes in 178,746 blocks
==880==         suppressed: 0 bytes in 0 blocks
==880== Rerun with --leak-check=full to see details of leaked memory
==880== 
==880== For counts of detected and suppressed errors, rerun with: -v
==880== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)
Comment 1 Albert Astals Cid 2012-01-10 23:08:38 UTC
Thomas, can you have a look?
Comment 2 Thomas Freitag 2012-01-12 01:34:48 UTC
Created attachment 55480 [details] [review]
breaks endless loop in markObject

The SIGSEGV is caused by an endless loop in markObject. This patch solves it. Beside that, in pdfunite and pdfseparate the initializing of the static variable globalParams was missing. This can cause also segmentation faults, if a PDF references not embedded fonts, therefore I corrected that, too.
Comment 3 Albert Astals Cid 2012-01-13 10:12:37 UTC
isn't the >9 a bit too hard? What if the file had an object that was already at gen 9?
Comment 4 Thomas Freitag 2012-01-13 23:53:08 UTC
It marks references, and if it is already marked, also all objects used by this reference are already marked, so in case of pdfseparate and pdfunite You can break immediately (>1). But I use this functionality also in other cases, i.e. when removing spot colors from a PDF. In this case I also to remove remove the spot colorspace objects from the PDF if no more referenced, and in this case I need the counter. (If I'll get some time in future and poppler community is interested, I could also add this tool, removing and / or replacing spot colors, but I think this is a more or less scientific use, and not a lot people are really interested in such a feature)
Comment 5 Albert Astals Cid 2012-01-15 06:08:17 UTC
Commited, will be in next release

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.