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

Integer Overflow in compound_document::read_sector leads to Heap Buffer Overflow #626

Open
kobrineli opened this issue Apr 20, 2022 · 0 comments

Comments

@kobrineli
Copy link

kobrineli commented Apr 20, 2022

Hi! I've been fuzzing your projects and found an input, that leads to integer overflow and source/detail/cryptography/compound_document.cpp:591.
Executing with this input leads to later heap buffer overflow in /xlnt/source/detail/cryptography/compound_document.cpp:975.

Steps for reproducing:

  1. Build docker container for xlnt from https://github.com/ispras/oss-sydr-fuzz/tree/master/projects/xlnt
  2. Run docker container and execute /load_fuzzer overflow_input.txt with this input:
    crash-sydr_dfe5d3280e194d75ab9efc14ba3a679e304690a2_int_overflow_6_unsigned.txt

You will see something like this:

    /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/ext/new_allocator.h:147:27: runtime error: implicit conversion from type 'char' of value -48 (8-bit, signed) to type 'unsigned char' changed the value to 208 (8-bit, unsigned)
    SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/ext/new_allocator.h:147:27 in 
    /xlnt/source/detail/cryptography/compound_document.cpp:532:40: runtime error: shift exponent 201 is too large for 64-bit type 'std::size_t' (aka 'unsigned long')
    SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /xlnt/source/detail/cryptography/compound_document.cpp:532:40 in 
    /xlnt/source/detail/cryptography/compound_document.cpp:591:80: runtime error: unsigned integer overflow: 512 * 18446744073709551615 cannot be represented in type 'unsigned long'
    SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /xlnt/source/detail/cryptography/compound_document.cpp:591:80 in 
    /xlnt/source/detail/cryptography/compound_document.cpp:591:64: runtime error: unsigned integer overflow: 512 + 18446744073709551104 cannot be represented in type 'unsigned long'
    SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /xlnt/source/detail/cryptography/compound_document.cpp:591:64 in 
    =================================================================
    ==17==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x615000002380 at pc 0x0000004dafd7 bp 0x7fffffffb8b0 sp 0x7fffffffb078
    READ of size 128 at 0x615000002380 thread T0
        #0 0x4dafd6 in __asan_memcpy /llvm-project/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:22:3
        #1 0x10a16a9 in xlnt::detail::compound_document::read_directory() /xlnt/source/detail/cryptography/compound_document.cpp:975:34
        #2 0x109e3eb in xlnt::detail::compound_document::compound_document(std::istream&) /xlnt/source/detail/cryptography/compound_document.cpp:517:5
        #3 0x986850 in (anonymous namespace)::decrypt_xlsx(std::vector<unsigned char, std::allocator<unsigned char> > const&, std::__cxx11::basic_string<char16_t, std::char_traits<char16_t>, std::allocator<char16_t> > const&) /xlnt/source/detail/cryptography/xlsx_crypto_consumer.cpp:320:37
        #4 0x98604a in xlnt::detail::decrypt_xlsx(std::vector<unsigned char, std::allocator<unsigned char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /xlnt/source/detail/cryptography/xlsx_crypto_consumer.cpp:339:12
        #5 0x9877fe in xlnt::detail::xlsx_consumer::read(std::istream&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /xlnt/source/detail/cryptography/xlsx_crypto_consumer.cpp:345:28
        #6 0x547148 in xlnt::workbook::load(std::istream&) /xlnt/source/workbook/workbook.cpp:901:22
        #7 0x56dfa7 in xlnt::workbook::load(std::vector<unsigned char, std::allocator<unsigned char> > const&) /xlnt/source/workbook/workbook.cpp:919:5
        #8 0x514db2 in LLVMFuzzerTestOneInput /xlnt/build/../load_fuzzer.cc:9:23
        #9 0x441d51 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:611:15
        #10 0x42c36c in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:324:6
        #11 0x4320db in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:860:9
        #12 0x45ae22 in main /llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
        #13 0x7ffff7a760b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16
        #14 0x426c8d in _start (/load_fuzzer+0x426c8d)
    
    0x615000002380 is located 768 bytes to the right of 512-byte region [0x615000001e80,0x615000002080) allocated by thread T0 here:
        #0 0x51235d in operator new(unsigned long) /llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:95:3
        #1 0x110db5e in __gnu_cxx::new_allocator<xlnt::detail::compound_document_entry>::allocate(unsigned long, void const*) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/ext/new_allocator.h:114:27
        #2 0x110d9ca in std::allocator_traits<std::allocator<xlnt::detail::compound_document_entry> >::allocate(std::allocator<xlnt::detail::compound_document_entry>&, unsigned long) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/alloc_traits.h:444:20
        #3 0x110cf2e in std::_Vector_base<xlnt::detail::compound_document_entry, std::allocator<xlnt::detail::compound_document_entry> >::_M_allocate(unsigned long) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:343:20
        #4 0x111bf85 in void std::vector<xlnt::detail::compound_document_entry, std::allocator<xlnt::detail::compound_document_entry> >::_M_realloc_insert<xlnt::detail::compound_document_entry>(__gnu_cxx::__normal_iterator<xlnt::detail::compound_document_entry*, std::vector<xlnt::detail::compound_document_entry, std::allocator<xlnt::detail::compound_document_entry> > >, xlnt::detail::compound_document_entry&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/vector.tcc:440:33
        #5 0x111b705 in void std::vector<xlnt::detail::compound_document_entry, std::allocator<xlnt::detail::compound_document_entry> >::emplace_back<xlnt::detail::compound_document_entry>(xlnt::detail::compound_document_entry&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/vector.tcc:121:4
        #6 0x10bea14 in std::vector<xlnt::detail::compound_document_entry, std::allocator<xlnt::detail::compound_document_entry> >::push_back(xlnt::detail::compound_document_entry&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:1201:9
        #7 0x10a0c57 in xlnt::detail::compound_document::read_directory() /xlnt/source/detail/cryptography/compound_document.cpp:949:18
       #8 0x109e3eb in xlnt::detail::compound_document::compound_document(std::istream&) /xlnt/source/detail/cryptography/compound_document.cpp:517:5
        #9 0x986850 in (anonymous namespace)::decrypt_xlsx(std::vector<unsigned char, std::allocator<unsigned char> > const&, std::__cxx11::basic_string<char16_t, std::char_traits<char16_t>, std::allocator<char16_t> > const&) /xlnt/source/detail/cryptography/xlsx_crypto_consumer.cpp:320:37
        #10 0x98604a in xlnt::detail::decrypt_xlsx(std::vector<unsigned char, std::allocator<unsigned char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /xlnt/source/detail/cryptography/xlsx_crypto_consumer.cpp:339:12
        #11 0x9877fe in xlnt::detail::xlsx_consumer::read(std::istream&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /xlnt/source/detail/cryptography/xlsx_crypto_consumer.cpp:345:28
        #12 0x547148 in xlnt::workbook::load(std::istream&) /xlnt/source/workbook/workbook.cpp:901:22
        #13 0x56dfa7 in xlnt::workbook::load(std::vector<unsigned char, std::allocator<unsigned char> > const&) /xlnt/source/workbook/workbook.cpp:919:5
        #14 0x514db2 in LLVMFuzzerTestOneInput /xlnt/build/../load_fuzzer.cc:9:23
        #15 0x441d51 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:611:15
        #16 0x42c36c in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:324:6
        #17 0x4320db in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:860:9
        #18 0x45ae22 in main /llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
        #19 0x7ffff7a760b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16
    
    SUMMARY: AddressSanitizer: heap-buffer-overflow /llvm-project/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:22:3 in __asan_memcpy
    Shadow bytes around the buggy address:
      0x0c2a7fff8420: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x0c2a7fff8430: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x0c2a7fff8440: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x0c2a7fff8450: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x0c2a7fff8460: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
    =>0x0c2a7fff8470:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x0c2a7fff8480: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x0c2a7fff8490: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x0c2a7fff84a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x0c2a7fff84b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x0c2a7fff84c0: 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
    ==17==ABORTING

OS version: ubuntu 20.04

xlnt version: d88c901

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

1 participant