tfussell / xlnt

:bar_chart: Cross-platform user-friendly xlsx library for C++11+
Other
1.49k stars 418 forks source link

Hang and out-of-memory in xlnt::worksheet::add_column_properties() #596

Open apach301 opened 2 years ago

apach301 commented 2 years ago

Hi, I was playing with libFuzzer and found that function xlnt::workbook::load hangs when opening xlsx-file. It also consumes all available RAM when hanging.

The bug reproduced when opening hang-2f3173eabd98df7618997f8bfb42e7dc05c6941a.txt file. You can use docker and fuzz targets from oss-sydr-fuzz to reproduce error:

/load_sydr hang-2f3173eabd98df7618997f8bfb42e7dc05c6941a.txt

Stack trace under gdb:

(gdb) bt
#0  0x00000000004335bc in std::forward<xlnt::column_t const&> (__t=...) at /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/move.h:75
#1  0x0000000000480619 in std::_Tuple_impl<0ul, xlnt::column_t const&>::_Tuple_impl (this=0x7ffc0b9b2088, __in=...) at /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/tuple:360
#2  0x00000000004805bd in std::tuple<xlnt::column_t const&>::tuple (this=0x7ffc0b9b2088) at /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/tuple:642
#3  0x0000000000480582 in __gnu_cxx::new_allocator<std::__detail::_Hash_node<std::pair<xlnt::column_t const, xlnt::column_properties>, true> >::construct<std::pair<xlnt::column_t const, xlnt::column_properties>, std::piecewise_construct_t const&, std::tuple<xlnt::column_t const&>, std::tuple<> >(std::pair<xlnt::column_t const, xlnt::column_properties>*, std::piecewise_construct_t const&, std::tuple<xlnt::column_t const&>&&, std::tuple<>&&) (this=0x2188d98, __p=0x2e462798, __args=..., __args=..., __args=...) at /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/ext/new_allocator.h:147
#4  0x0000000000480527 in std::allocator_traits<std::allocator<std::__detail::_Hash_node<std::pair<xlnt::column_t const, xlnt::column_properties>, true> > >::construct<std::pair<xlnt::column_t const, xlnt::column_properties>, std::piecewise_construct_t const&, std::tuple<xlnt::column_t const&>, std::tuple<> >(std::allocator<std::__detail::_Hash_node<std::pair<xlnt::column_t const, xlnt::column_properties>, true> >&, std::pair<xlnt::column_t const, xlnt::column_properties>*, std::piecewise_construct_t const&, std::tuple<xlnt::column_t const&>&&, std::tuple<>&&) (__a=..., __p=0x2e462798, __args=..., __args=..., __args=...)
    at /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/alloc_traits.h:484
#5  0x0000000000480276 in std::__detail::_Hashtable_alloc<std::allocator<std::__detail::_Hash_node<std::pair<xlnt::column_t const, xlnt::column_properties>, true> > >::_M_allocate_node<std::piecewise_construct_t const&, std::tuple<xlnt::column_t const&>, std::tuple<> >(std::piecewise_construct_t const&, std::tuple<xlnt::column_t const&>&&, std::tuple<>&&) (this=0x2188d98, __args=..., __args=..., __args=...)
    at /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/hashtable_policy.h:2086
#6  0x0000000000480172 in std::__detail::_Map_base<xlnt::column_t, std::pair<xlnt::column_t const, xlnt::column_properties>, std::allocator<std::pair<xlnt::column_t const, xlnt::column_properties> >, std::__detail::_Select1st, std::equal_to<xlnt::column_t>, std::hash<xlnt::column_t>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true>, true>::operator[] (this=0x2188d98, __k=...) at /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/hashtable_policy.h:701
#7  0x000000000047615d in std::unordered_map<xlnt::column_t, xlnt::column_properties, std::hash<xlnt::column_t>, std::equal_to<xlnt::column_t>, std::allocator<std::pair<xlnt::column_t const, xlnt::column_properties> > >::operator[] (this=0x2188d98, __k=...) at /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/unordered_map.h:985
#8  0x00000000004728cf in xlnt::worksheet::add_column_properties (this=0x7ffc0b9b47e0, column=..., props=...) at /xlnt/source/worksheet/worksheet.cpp:1086
#9  0x00000000004a05c1 in xlnt::detail::xlsx_consumer::read_worksheet_begin (this=0x7ffc0b9b8d40, Python Exception <class 'gdb.error'> There is no member named _M_p.: 
rel_id=) at /xlnt/source/detail/serialization/xlsx_consumer.cpp:724
#10 0x00000000004998f5 in xlnt::detail::xlsx_consumer::read_worksheet (this=0x7ffc0b9b8d40, Python Exception <class 'gdb.error'> There is no member named _M_p.: 
rel_id=) at /xlnt/source/detail/serialization/xlsx_consumer.cpp:417
#11 0x00000000004b0306 in xlnt::detail::xlsx_consumer::read_part (this=0x7ffc0b9b8d40, rel_chain=std::vector of length 2, capacity 2 = {...}) at /xlnt/source/detail/serialization/xlsx_consumer.cpp:1543
#12 0x00000000004bd332 in xlnt::detail::xlsx_consumer::read_office_document (this=0x7ffc0b9b8d40, Python Exception <class 'gdb.error'> There is no member named _M_p.: 
content_type=) at /xlnt/source/detail/serialization/xlsx_consumer.cpp:2051
#13 0x00000000004b0169 in xlnt::detail::xlsx_consumer::read_part (this=0x7ffc0b9b8d40, rel_chain=std::vector of length 1, capacity 1 = {...}) at /xlnt/source/detail/serialization/xlsx_consumer.cpp:1495
#14 0x0000000000499664 in xlnt::detail::xlsx_consumer::populate_workbook (this=0x7ffc0b9b8d40, streaming=false) at /xlnt/source/detail/serialization/xlsx_consumer.cpp:1645
#15 0x0000000000498e1d in xlnt::detail::xlsx_consumer::read (this=0x7ffc0b9b8d40, source=...) at /xlnt/source/detail/serialization/xlsx_consumer.cpp:401
#16 0x000000000040dcad in xlnt::workbook::load (this=0x7ffc0b9b9018, stream=...) at /xlnt/source/workbook/workbook.cpp:894
#17 0x00000000004142bf in xlnt::workbook::load (this=0x7ffc0b9b9018, data=std::vector of length 65237, capacity 65237 = {...}) at /xlnt/source/workbook/workbook.cpp:919
#18 0x000000000040739f in LLVMFuzzerTestOneInput (data=<optimized out>, size=<optimized out>) at ../load_sydr.cc:13
#19 0x00007f5434d3b0b3 in __libc_start_main (main=0x407440 <main(int, char**)>, argc=2, argv=0x7ffc0b9b9148, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7ffc0b9b9138)
    at ../csu/libc-start.c:308
#20 0x000000000040724e in _start () at /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/iostream:74