podofo: heap-based buffer overflow in PoDoFo::PdfSimpleEncoding::ConvertToEncoding (PdfEncoding.cpp)

Description:
podofo is a C++ library to work with the PDF file format.

A fuzz on it through the podofotxt2pdf command line tool reavealed an heap overflow. This post will be forwarded on the upstream mailing list.

The complete ASan output:

# podofotxt2pdf $FILE out.pdf
==12895==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6310000c47ff at pc 0x7f7434e576ea bp 0x7ffde7868b70 sp 0x7ffde7868b68
READ of size 1 at 0x6310000c47ff thread T0
    #0 0x7f7434e576e9 in PoDoFo::PdfSimpleEncoding::ConvertToEncoding(PoDoFo::PdfString const&, PoDoFo::PdfFont const*) const /tmp/portage/app-text/podofo-0.9.5/work/podofo-0.9.5/src/base/PdfEncoding.cpp:484:21
    #1 0x7f7435337c7f in PoDoFo::PdfFont::WriteStringToStream(PoDoFo::PdfString const&, PoDoFo::PdfStream*) /tmp/portage/app-text/podofo-0.9.5/work/podofo-0.9.5/src/doc/PdfFont.cpp:144:47
    #2 0x7f74356a5374 in PoDoFo::PdfPainter::DrawText(double, double, PoDoFo::PdfString const&, long) /tmp/portage/app-text/podofo-0.9.5/work/podofo-0.9.5/src/doc/PdfPainter.cpp:824:14
    #3 0x519755 in draw(char*, PoDoFo::PdfDocument*, bool, char const*) /tmp/portage/app-text/podofo-0.9.5/work/podofo-0.9.5/tools/podofotxt2pdf/podofotxt2pdf.cpp:94:25
    #4 0x51aa52 in init(char const*, char const*, bool, char const*) /tmp/portage/app-text/podofo-0.9.5/work/podofo-0.9.5/tools/podofotxt2pdf/podofotxt2pdf.cpp:165:5
    #5 0x51c253 in main /tmp/portage/app-text/podofo-0.9.5/work/podofo-0.9.5/tools/podofotxt2pdf/podofotxt2pdf.cpp:212:7
    #6 0x7f743363f78f in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #7 0x41ccb8 in _start (/usr/bin/podofotxt2pdf+0x41ccb8)

0x6310000c47ff is located 0 bytes to the right of 65535-byte region [0x6310000b4800,0x6310000c47ff)
allocated by thread T0 here:
    #0 0x4dc585 in calloc /tmp/portage/sys-libs/compiler-rt-sanitizers-4.0.0/work/compiler-rt-4.0.0.src/lib/asan/asan_malloc_linux.cc:74
    #1 0x7f7434f9f978 in PoDoFo::podofo_calloc(unsigned long, unsigned long) /tmp/portage/app-text/podofo-0.9.5/work/podofo-0.9.5/src/base/PdfMemoryManagement.cpp:136:9
    #2 0x7f7434e51913 in PoDoFo::PdfSimpleEncoding::InitEncodingTable() /tmp/portage/app-text/podofo-0.9.5/work/podofo-0.9.5/src/base/PdfEncoding.cpp:370:47
    #3 0x7f7434e55af1 in PoDoFo::PdfSimpleEncoding::ConvertToEncoding(PoDoFo::PdfString const&, PoDoFo::PdfFont const*) const /tmp/portage/app-text/podofo-0.9.5/work/podofo-0.9.5/src/base/PdfEncoding.cpp:459:51
    #4 0x7f7435337c7f in PoDoFo::PdfFont::WriteStringToStream(PoDoFo::PdfString const&, PoDoFo::PdfStream*) /tmp/portage/app-text/podofo-0.9.5/work/podofo-0.9.5/src/doc/PdfFont.cpp:144:47
    #5 0x7f74356a5374 in PoDoFo::PdfPainter::DrawText(double, double, PoDoFo::PdfString const&, long) /tmp/portage/app-text/podofo-0.9.5/work/podofo-0.9.5/src/doc/PdfPainter.cpp:824:14
    #6 0x519755 in draw(char*, PoDoFo::PdfDocument*, bool, char const*) /tmp/portage/app-text/podofo-0.9.5/work/podofo-0.9.5/tools/podofotxt2pdf/podofotxt2pdf.cpp:94:25
    #7 0x51aa52 in init(char const*, char const*, bool, char const*) /tmp/portage/app-text/podofo-0.9.5/work/podofo-0.9.5/tools/podofotxt2pdf/podofotxt2pdf.cpp:165:5
    #8 0x51c253 in main /tmp/portage/app-text/podofo-0.9.5/work/podofo-0.9.5/tools/podofotxt2pdf/podofotxt2pdf.cpp:212:7
    #9 0x7f743363f78f in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289

SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/portage/app-text/podofo-0.9.5/work/podofo-0.9.5/src/base/PdfEncoding.cpp:484:21 in PoDoFo::PdfSimpleEncoding::ConvertToEncoding(PoDoFo::PdfString const&, PoDoFo::PdfFont const*) const
Shadow bytes around the buggy address:
  0x0c62800108a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c62800108b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c62800108c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c62800108d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c62800108e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c62800108f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00[07]
  0x0c6280010900: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c6280010910: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c6280010920: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c6280010930: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c6280010940: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==12895==ABORTING

Affected version:
0.9.5

Fixed version:
N/A

Commit fix:
N/A

Credit:
This bug was discovered by Agostino Sarubbo of Gentoo.

CVE:
CVE-2017-7379

Reproducer:
https://github.com/asarubbo/poc/blob/master/00249-podofo-heapoverflow-PdfEncoding_cpp

Timeline:
2017-03-31: bug discovered and reported to upstream
2017-03-31: blog post about the issue
2017-03-31: CVE assigned

Note:
This bug was found with American Fuzzy Lop.

Permalink:

podofo: heap-based buffer overflow in PoDoFo::PdfSimpleEncoding::ConvertToEncoding (PdfEncoding.cpp)

This entry was posted in advisories, security. Bookmark the permalink.

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.