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 ----------
I can reproduce also on master. Will fix in 2.4.x and master
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.
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.
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.
Fixed in the 2.4.x branch https://cgit.freedesktop.org/exempi/commit/?h=exempi-2.4-branch&id=c26d5beb60a5a85f76259f50ed3e08c8169b0a0c
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.