Bug 100397 - Crash with malformed file (jpeg posing as .pdf)
Summary: Crash with malformed file (jpeg posing as .pdf)
Status: RESOLVED FIXED
Alias: None
Product: exempi
Classification: Unclassified
Component: Problems (show other bugs)
Version: unspecified
Hardware: x86-64 (AMD64) Linux (All)
: medium normal
Assignee: Hubert Figuiere
QA Contact: Hubert Figuiere
URL:
Whiteboard: [release:2.4.3]
Keywords:
Depends on:
Blocks:
 
Reported: 2017-03-25 23:00 UTC by Sami Liedes
Modified: 2017-08-04 02:26 UTC (History)
0 users

See Also:
i915 platform:
i915 features:


Attachments
test case (17.42 KB, application/pdf)
2017-03-25 23:00 UTC, Sami Liedes
Details

Description Sami Liedes 2017-03-25 23:00:18 UTC
Created attachment 130459 [details]
test case

exempi 2.4.2 (Debian unstable, x86_64) crashes reproducibly when run on the attached corrupted PDF file.

----------
$ exempi -x crash.pdf
processing file crash.pdf
dump_xmp for file crash.pdf
Segmentation fault
----------

Valgrind gives the following information:

----------
$ LD_LIBRARY_PATH=debug/exempi-2.4.2/exempi/.libs/ valgrind debug/exempi-2.4.2/exempi/.libs/exempi -x crash.pdf 
Memcheck, a memory error detector
Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
Command: debug/exempi-2.4.2/exempi/.libs/exempi -x crash.pdf

processing file crash.pdf
dump_xmp for file crash.pdf
Invalid read of size 1
   at 0x4F60348: ??? (ReconcileTIFF.cpp:239)
   by 0x4F60434: TrimTrailingSpaces (ReconcileTIFF.cpp:236)
   by 0x4F60434: TrimTrailingSpaces (ReconcileTIFF.cpp:260)
   by 0x4F60434: ImportSingleTIFF_ASCII (ReconcileTIFF.cpp:507)
   by 0x4F60434: ??? (ReconcileTIFF.cpp:709)
   by 0x4F61B27: ??? (ReconcileTIFF.cpp:1259)
   by 0x4F62763: PhotoDataUtils::Import2WayExif(TIFF_Manager const&, TXMPMeta<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*, int) (ReconcileTIFF.cpp:2008)
   by 0x4F5F654: ImportPhotoData(TIFF_Manager const&, IPTC_Manager const&, PSIR_Manager const&, int, TXMPMeta<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*, unsigned int) (ReconcileLegacy.cpp:87)
   by 0x4EFBB3A: JPEG_MetaHandler::ProcessXMP() (JPEG_Handler.cpp:656)
   by 0x4EE9A85: XMPFiles::GetXMP(TXMPMeta<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*, char const**, unsigned int*, XMP_PacketInfo*) (XMPFiles.cpp:1303)
   by 0x4EE6FF9: WXMPFiles_GetXMP_1 (WXMPFiles.cpp:332)
   by 0x4EA075A: TXMPFiles<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::GetXMP(TXMPMeta<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, XMP_PacketInfo*) (TXMPFiles.incl_cpp:382)
   by 0x4E9AA95: xmp_files_get_new_xmp (exempi.cpp:331)
   by 0x10A844: get_xmp_from_file(char const*, bool, bool) (main.cpp:237)
   by 0x109E07: dump_xmp (main.cpp:250)
   by 0x109E07: process_file (main.cpp:340)
   by 0x109E07: main (main.cpp:187)
 Address 0x3692b07f is not stack'd, malloc'd or (recently) free'd


Process terminating with default action of signal 11 (SIGSEGV)
 Access not within mapped region at address 0x3692B07F
   at 0x4F60348: ??? (ReconcileTIFF.cpp:239)
   by 0x4F60434: TrimTrailingSpaces (ReconcileTIFF.cpp:236)
   by 0x4F60434: TrimTrailingSpaces (ReconcileTIFF.cpp:260)
   by 0x4F60434: ImportSingleTIFF_ASCII (ReconcileTIFF.cpp:507)
   by 0x4F60434: ??? (ReconcileTIFF.cpp:709)
   by 0x4F61B27: ??? (ReconcileTIFF.cpp:1259)
   by 0x4F62763: PhotoDataUtils::Import2WayExif(TIFF_Manager const&, TXMPMeta<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*, int) (ReconcileTIFF.cpp:2008)
   by 0x4F5F654: ImportPhotoData(TIFF_Manager const&, IPTC_Manager const&, PSIR_Manager const&, int, TXMPMeta<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*, unsigned int) (ReconcileLegacy.cpp:87)
   by 0x4EFBB3A: JPEG_MetaHandler::ProcessXMP() (JPEG_Handler.cpp:656)
   by 0x4EE9A85: XMPFiles::GetXMP(TXMPMeta<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*, char const**, unsigned int*, XMP_PacketInfo*) (XMPFiles.cpp:1303)
   by 0x4EE6FF9: WXMPFiles_GetXMP_1 (WXMPFiles.cpp:332)
   by 0x4EA075A: TXMPFiles<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::GetXMP(TXMPMeta<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, XMP_PacketInfo*) (TXMPFiles.incl_cpp:382)
   by 0x4E9AA95: xmp_files_get_new_xmp (exempi.cpp:331)
   by 0x10A844: get_xmp_from_file(char const*, bool, bool) (main.cpp:237)
   by 0x109E07: dump_xmp (main.cpp:250)
   by 0x109E07: process_file (main.cpp:340)
   by 0x109E07: main (main.cpp:187)
 If you believe this happened as a result of a stack
 overflow in your program's main thread (unlikely but
 possible), you can try to increase the size of the
 main thread stack using the --main-stacksize= flag.
 The main thread stack size used in this run was 8388608.

HEAP SUMMARY:
    in use at exit: 83,996 bytes in 706 blocks
  total heap usage: 1,133 allocs, 427 frees, 177,041 bytes allocated

LEAK SUMMARY:
   definitely lost: 0 bytes in 0 blocks
   indirectly lost: 0 bytes in 0 blocks
     possibly lost: 0 bytes in 0 blocks
   still reachable: 83,996 bytes in 706 blocks
        suppressed: 0 bytes in 0 blocks
Rerun with --leak-check=full to see details of leaked memory

For counts of detected and suppressed errors, rerun with: -v
ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault
----------

Here's a GDB backtrace:

----------
$ LD_LIBRARY_PATH=debug/exempi-2.4.2/exempi/.libs/ gdb --args debug/exempi-2.4.2/exempi/.libs/exempi -x crash.pdf 
Reading symbols from debug/exempi-2.4.2/exempi/.libs/exempi...done.
(gdb) r
Starting program: /home/sliedes/scratch/afl/exempi/debug/exempi-2.4.2/exempi/.libs/exempi -x crash.pdf
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
processing file crash.pdf
dump_xmp for file crash.pdf

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7b41348 in TrimTrailingSpaces (firstChar=firstChar@entry=0x5555857cdad0 <error: Cannot access memory at address 0x5555857cdad0>, origLen=origLen@entry=12336) at ReconcileTIFF.cpp:239
239		if ( (*lastChar != ' ') && (*lastChar != 0) ) return origLen;	// Nothing to do.
(gdb) bt
#0  0x00007ffff7b41348 in TrimTrailingSpaces (firstChar=firstChar@entry=0x5555857cdad0 <error: Cannot access memory at address 0x5555857cdad0>, origLen=origLen@entry=12336) at ReconcileTIFF.cpp:239
#1  0x00007ffff7b41435 in TrimTrailingSpaces (origLen=12336, firstChar=0x5555857cdad0 <error: Cannot access memory at address 0x5555857cdad0>) at ReconcileTIFF.cpp:236
#2  TrimTrailingSpaces (info=0x7fffffffd4c0, info=0x7fffffffd4c0) at ReconcileTIFF.cpp:260
#3  ImportSingleTIFF_ASCII (xmpProp=0x7ffff7b79791 "CameraOwnerName", xmpNS=0x7ffff7b6f34a "http://cipa.jp/exif/1.0/", xmp=0x555555779020, tagInfo=...) at ReconcileTIFF.cpp:507
#4  ImportSingleTIFF (tagInfo=..., nativeEndian=nativeEndian@entry=false, xmp=xmp@entry=0x555555779020, xmpNS=0x7ffff7b6f34a "http://cipa.jp/exif/1.0/", xmpProp=0x7ffff7b79791 "CameraOwnerName")
    at ReconcileTIFF.cpp:709
#5  0x00007ffff7b42b28 in ImportTIFF_StandardMappings (ifd=ifd@entry=2 '\002', tiff=..., xmp=xmp@entry=0x555555779020) at ReconcileTIFF.cpp:1259
#6  0x00007ffff7b43764 in PhotoDataUtils::Import2WayExif (exif=..., xmp=0x555555779020, iptcDigestState=<optimized out>) at ReconcileTIFF.cpp:2008
#7  0x00007ffff7b40655 in ImportPhotoData (exif=..., iptc=..., psir=..., iptcDigestState=1, xmp=0x555555779020, options=<optimized out>) at ReconcileLegacy.cpp:87
#8  0x00007ffff7adcb3b in JPEG_MetaHandler::ProcessXMP (this=0x555555778fd0) at JPEG_Handler.cpp:656
#9  0x00007ffff7acaa86 in XMPFiles::GetXMP (this=0x555555778df0, xmpObj=0x7fffffffd930, xmpPacket=0x7fffffffd928, xmpPacketLen=0x7fffffffd924, packetInfo=0x0) at XMPFiles.cpp:1303
#10 0x00007ffff7ac7ffa in WXMPFiles_GetXMP_1 (xmpObjRef=0x555555778df0, xmpRef=0x55555577d800, clientPacket=0x0, packetInfo=0x0, 
    SetClientString=0x7ffff7a7dbf0 <TXMPFiles<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::SetClientString(void*, char const*, unsigned int)>, wResult=0x7fffffffd980)
    at WXMPFiles.cpp:332
#11 0x00007ffff7a8175b in TXMPFiles<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::GetXMP (this=this@entry=0x555555773fd0, xmpObj=xmpObj@entry=0x555555771bb0, 
    xmpPacket=xmpPacket@entry=0x0, packetInfo=packetInfo@entry=0x0) at ../public/include/client-glue/TXMPFiles.incl_cpp:382
#12 0x00007ffff7a7ba96 in xmp_files_get_new_xmp (xf=0x555555773fd0) at exempi.cpp:331
#13 0x0000555555556845 in get_xmp_from_file (filename=<optimized out>, no_reconcile=<optimized out>, is_an_xmp=<optimized out>) at main.cpp:237
#14 0x0000555555555e08 in dump_xmp (outio=0x7ffff6927600 <_IO_2_1_stdout_>, is_an_xmp=<optimized out>, no_reconcile=<optimized out>, filename=0x7fffffffe191 "crash.pdf") at main.cpp:250
#15 process_file (output="", prop_value="", value_name="", action=0, dump_xml=true, write_in_place=false, is_an_xmp=<optimized out>, no_reconcile=<optimized out>, filename=0x7fffffffe191 "crash.pdf")
    at main.cpp:340
#16 main (argc=<optimized out>, argv=0x7fffffffdda8) at main.cpp:187
----------
Comment 1 Hubert Figuiere 2017-03-26 01:19:07 UTC
I can reproduce also on master.

Will fix in 2.4.x and master
Comment 2 Hubert Figuiere 2017-03-26 01:30:18 UTC
When build with AddressSanitizer, it catches a use of memcpy() with overlapping region.


This in the Adobe code and it says call to memcpy is marked as "audited" or not overlapping.
Comment 3 Hubert Figuiere 2017-03-26 01:58:06 UTC
I stand corrected. While the errors occurs, the crash below still happens.


BTW this is not even a valid PDF. file(2) identifies it as JPEG.
Comment 4 Hubert Figuiere 2017-03-26 03:02:29 UTC
It is a descent to the rabbit hole.

First the file trigger memcpy of overlapped region
Then it triggers the actual buffer overrun reported here.
Fixing it cause a std::logic_error (NULL initialisation for a std::string)
This logic_error cause a use-after-free in the error handling code

Good news, all of this will be fixed in a moment.


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.