Foxit PDF Reader 1.0.1.0925 - CPDF_StreamContentParser::~CPDF_StreamContentParser Heap-Based Memory Corruption

2016-06-13T00:00:00
ID EDB-ID:39940
Type exploitdb
Reporter Google Security Research
Modified 2016-06-13T00:00:00

Description

Foxit PDF Reader 1.0.1.0925 - CPDF_StreamContentParser::~CPDF_StreamContentParser Heap-Based Memory Corruption. Dos exploit for linux platform

                                        
                                            Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=741

We have identified the following memory corruption vulnerability in Foxit PDF Reader (version 1.0.1.0925 for Linux 64-bit), when started with a specially crafted PDF file in the following way:

$ MALLOC_CHECK_=3 DISPLAY=:1 FoxitReader /path/to/poc/file.pdf

The MALLOC_CHECK_=3 environment variable is used to enforce strict checks in the libc memory allocator, while DISPLAY=:1 is set due to the fact that we are testing the application with a virtual X server (Xvfb), but the issue should be equally reproducible with the program started with standard display settings, too.

An example excerpt from the crash log is as follows:

--- cut ---
*** Error in `FoxitReader': free(): invalid pointer: 0x0000000001930a60 ***
[New Thread 0x7fffdfa16700 (LWP 26721)]
[New Thread 0x7fffe0217700 (LWP 26720)]
[New Thread 0x7fffe0a18700 (LWP 26718)]
[New Thread 0x7fffe97cd700 (LWP 26717)]

Program received signal SIGABRT, Aborted.
0x00007ffff4fc0cb7 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56      ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) where
#0  0x00007ffff4fc0cb7 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x00007ffff4fc40a8 in __GI_abort () at abort.c:89
#2  0x00007ffff4ffd2f4 in __libc_message (do_abort=do_abort@entry=1, 
    fmt=fmt@entry=0x7ffff510b988 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175
#3  0x00007ffff500bef6 in malloc_printerr (ptr=<optimized out>, 
    str=0x7ffff5107a79 "free(): invalid pointer", action=1) at malloc.c:4996
#4  free_check (mem=<optimized out>, caller=<optimized out>) at hooks.c:298
#5  0x00000000007c823f in CPDF_StreamContentParser::~CPDF_StreamContentParser() ()
#6  0x00000000007c9504 in CPDF_ContentParser::Continue(IFX_Pause*, int) ()
#7  0x00000000007b97d9 in CPDF_PageObjects::ContinueParse(IFX_Pause*) ()
#8  0x000000000047a8b4 in CReader_PageEx::ParsePage (this=0x191f7e0)
    at ../../Readerlite/ReaderLite/src/frd_pageex.cpp:792
#9  0x0000000000490415 in CPDFViewerContentProvider::ParsePage (this=0x191ea60, nPage=0)
    at ../../Readerlite/ReaderLite/src/pdfviewercontentprovider.cpp:23
#10 0x000000000061da5f in CPDFViewerEx::DrawPages(CFX_DIBitmap*) ()
#11 0x000000000061daa8 in CPDFViewerEx::Paint(CFX_DIBitmap*) ()
#12 0x000000000061daf1 in CPDFViewerEx::ContinueRendering() ()
#13 0x000000000061de17 in CPDFViewerEx::GetRenderData(int) ()
#14 0x000000000044b274 in CPDF_TVPreview::paintEvent (this=0x191efe0)
    at ../../Readerlite/ReaderLite/src/preview.cpp:1305
#15 0x00007ffff74c2302 in QWidget::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#16 0x00007ffff7486c8c in QApplicationPrivate::notify_helper(QObject*, QEvent*) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#17 0x00007ffff748be56 in QApplication::notify(QObject*, QEvent*) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#18 0x00007ffff6340c2d in QCoreApplication::notifyInternal(QObject*, QEvent*) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#19 0x00007ffff74bcbea in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#20 0x00007ffff74bd5bc in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#21 0x00007ffff74bc786 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#22 0x00007ffff74bd5bc in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#23 0x00007ffff74bd434 in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#24 0x00007ffff74bc786 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#25 0x00007ffff74bd5bc in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#26 0x00007ffff74bc786 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#27 0x00007ffff74bd5bc in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#28 0x00007ffff74bd434 in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#29 0x00007ffff74bd434 in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#30 0x00007ffff74bd434 in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#31 0x00007ffff74bc786 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#32 0x00007ffff74bd5bc in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
---Type <return> to continue, or q <return> to quit---
   from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#33 0x00007ffff74bd434 in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#34 0x00007ffff74bc786 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#35 0x00007ffff7493233 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#36 0x00007ffff7493941 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#37 0x00007ffff74e0973 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#38 0x00007ffff7486c8c in QApplicationPrivate::notify_helper(QObject*, QEvent*) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#39 0x00007ffff748be56 in QApplication::notify(QObject*, QEvent*) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#40 0x00007ffff6340c2d in QCoreApplication::notifyInternal(QObject*, QEvent*) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#41 0x00007ffff6860ea6 in QGuiApplicationPrivate::processExposeEvent(QWindowSystemInterfacePrivate::ExposeEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
#42 0x00007ffff6861995 in QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
#43 0x00007ffff684a858 in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
#44 0x00007fffecc415b0 in ?? () from /usr/lib/x86_64-linux-gnu/qt5/plugins/platforms/libqxcb.so
#45 0x00007ffff4a79e04 in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#46 0x00007ffff4a7a048 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#47 0x00007ffff4a7a0ec in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#48 0x00007ffff638d98c in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#49 0x00007ffff633f96b in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#50 0x00007ffff63460e1 in QCoreApplication::exec() () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#51 0x0000000000439e25 in main (argc=2, argv=0x7fffffffe288) at ../../Readerlite/ReaderLite/src/main.cpp:310
--- cut ---

Attached are six proof of concept PDF files: three derived from an original file named 172.pdf in our original corpus, and three derived from 5659.pdf. While the two groups of files generate crashes with slightly different stack traces, the overall symptoms are similar enough to assume they expose the same bug in the code.


Proof of Concept:
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/39940.zip