Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Heap-buffer-overflow in podofo 0.10.0(main/PdfEncrypt.cpp:1132:5 in PoDoFo::PdfEncryptRC4::PdfEncryptRC4) #72

Closed
longuu9 opened this issue Apr 25, 2023 · 2 comments

Comments

@longuu9
Copy link

longuu9 commented Apr 25, 2023

We found a heap-buffer-overflow in podofo 0.10.0(main/PdfEncrypt.cpp:1132:5 in PoDoFo::PdfEncryptRC4::PdfEncryptRC4).

Command Input

podofopdfinfo poc_file

poc_file is attached.

Sanitizer Dump

==3975233==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000122f at pc 0x0000004ab677 bp 0x7ffc5060df20 sp 0x7ffc5060d6e8
READ of size 32 at 0x60300000122f thread T0
    #0 0x4ab676 in __asan_memcpy /root/test/fuzzing_python/llvm-project-llvmorg-12.0.0/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:22:3
    #1 0x64570f in PoDoFo::PdfEncryptRC4::PdfEncryptRC4(PoDoFo::PdfString, PoDoFo::PdfString, PoDoFo::PdfPermissions, int, PoDoFo::PdfEncryptAlgorithm, int, bool) /root/target/Invariants/podofo-0.10.0/src/podofo/main/PdfEncrypt.cpp:1132:5
    #2 0x638356 in PoDoFo::PdfEncrypt::CreateFromObject(PoDoFo::PdfObject const&) /root/target/Invariants/podofo-0.10.0/src/podofo/main/PdfEncrypt.cpp:556:43
    #3 0x79b3a8 in PoDoFo::PdfParser::ReadObjects(PoDoFo::InputStreamDevice&) /root/target/Invariants/podofo-0.10.0/src/podofo/main/PdfParser.cpp:631:29
    #4 0x798f13 in PoDoFo::PdfParser::Parse(PoDoFo::InputStreamDevice&, bool) /root/target/Invariants/podofo-0.10.0/src/podofo/main/PdfParser.cpp:83:9
    #5 0x71c42e in PoDoFo::PdfMemDocument::loadFromDevice(std::shared_ptr<PoDoFo::InputStreamDevice> const&, std::basic_string_view<char, std::char_traits<char> > const&) /root/target/Invariants/podofo-0.10.0/src/podofo/main/PdfMemDocument.cpp:148:12
    #6 0x71dcdd in PoDoFo::PdfMemDocument::LoadFromDevice(std::shared_ptr<PoDoFo::InputStreamDevice> const&, std::basic_string_view<char, std::char_traits<char> > const&) /root/target/Invariants/podofo-0.10.0/src/podofo/main/PdfMemDocument.cpp:137:5
    #7 0x71d8eb in PoDoFo::PdfMemDocument::Load(std::basic_string_view<char, std::char_traits<char> > const&, std::basic_string_view<char, std::char_traits<char> > const&) /root/target/Invariants/podofo-0.10.0/src/podofo/main/PdfMemDocument.cpp:119:5
    #8 0x4e1be9 in PdfInfoHelper::PdfInfoHelper(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /root/target/Invariants/podofo-0.10.0/tools/podofopdfinfo/pdfinfo.cpp:16:12
    #9 0x4e06b7 in main /root/target/Invariants/podofo-0.10.0/tools/podofopdfinfo/podofopdfinfo.cpp:94:23
    #10 0x7f5ed7b54082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:308:16
    #11 0x43106d in _start (/root/target/Invariants/podofo-0.10.0/build_clang/target/podofopdfinfo+0x43106d)

0x60300000122f is located 0 bytes to the right of 31-byte region [0x603000001210,0x60300000122f)
allocated by thread T0 here:
    #0 0x4dd3dd in operator new(unsigned long) /root/test/fuzzing_python/llvm-project-llvmorg-12.0.0/compiler-rt/lib/asan/asan_new_delete.cpp:99:3
    #1 0x7f5ed800487f in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::reserve(unsigned long) (/lib/x86_64-linux-gnu/libstdc++.so.6+0x14387f)
    #2 0x87564a in PoDoFo::StandardStreamDevice::readChar(char&) /root/target/Invariants/podofo-0.10.0/src/podofo/auxiliary/StreamDevice.cpp:290:12
    #3 0x868d29 in PoDoFo::InputStream::Read(char&) /root/target/Invariants/podofo-0.10.0/src/podofo/auxiliary/InputStream.cpp:53:12
    #4 0x7e319a in readHexString(PoDoFo::InputStreamDevice&, PoDoFo::charbuff_t<void>&) /root/target/Invariants/podofo-0.10.0/src/podofo/main/PdfTokenizer.cpp:801:16
LLVMSymbolizer: error reading file: No such file or directory
    #5 0x7ffc50612342  ([stack]+0x20342)

SUMMARY: AddressSanitizer: heap-buffer-overflow /root/test/fuzzing_python/llvm-project-llvmorg-12.0.0/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:22:3 in __asan_memcpy
Shadow bytes around the buggy address:
  0x0c067fff81f0: 00 fa fa fa 00 00 00 00 fa fa 00 00 00 fa fa fa
  0x0c067fff8200: fd fd fd fa fa fa 00 00 00 fa fa fa fd fd fd fa
  0x0c067fff8210: fa fa 00 00 00 fa fa fa 00 00 00 fa fa fa 00 00
  0x0c067fff8220: 00 fa fa fa fd fd fd fa fa fa 00 00 00 fa fa fa
  0x0c067fff8230: 00 00 00 fa fa fa 00 00 00 fa fa fa fd fd fd fa
=>0x0c067fff8240: fa fa 00 00 00[07]fa fa 00 00 00 fa fa fa 00 00
  0x0c067fff8250: 00 00 fa fa fd fd fd fa fa fa fd fd fd fa fa fa
  0x0c067fff8260: 00 00 00 fa fa fa fd fd fd fd fa fa 00 00 00 00
  0x0c067fff8270: fa fa 00 00 00 fa fa fa fd fd fd fa fa fa 00 00
  0x0c067fff8280: 00 fa fa fa 00 00 00 00 fa fa 00 00 00 fa fa fa
  0x0c067fff8290: fd fd fd fa fa fa fd fd fd fa fa fa fd fd fd 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
  Shadow gap:              cc
==3975233==ABORTING

Environment

  • OS: Ubuntu 20.04.1
  • clang:12.0.0
  • podofo:0.10.0

we built podofo with AddressSanitizer (ASAN) .

cmake -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang -DCMAKE_C_FLAGS="-O0 -fsanitize=address" -DCMAKE_CXX_FLAGS="-O0 -fsanitize=address"

poc_file.zip

@ceztko ceztko closed this as completed in 29d59f6 Apr 25, 2023
@ceztko
Copy link
Contributor

ceztko commented Apr 25, 2023

After the actual fix, there appears to be some memory leak that are probably pre-existing signaled by LeakSanitizer that is also available with -fsanitize=address, also with #69.

@ceztko
Copy link
Contributor

ceztko commented Apr 25, 2023

Interestingly enough, this kind of bugs was pre-existing in PoDoFo so it's just about time to receive some serious fuzzing. Unfortunately, fuzzing has its limits and I already see some other situations where similar bugs could be triggered by invalid /Encrypt dictionaries, see for example [1]. This would require more in depth evaluation of where to put such input validations, to ensure all the code paths are covered.

[1]

std::memcpy(m_oValue, oValue.GetRawData().data(), 32);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants