-
Notifications
You must be signed in to change notification settings - Fork 180
Closed
Description
I am running some experiments for AFLAPI and it has found a buffer-overflow (to be exact, out-of-bounds access after debugging) in toml::detail::location::reset()
. This bug seems to be harmless because it's hard to exploit. So I report here.
Environment: Ubuntu 20.04 + g++ 9.4.0
Drive program:
#include<iostream>
#include "toml.hpp"
int main(int argc, char** argv){
if(argc != 2)
return 0;
auto data = toml::parse((char*)argv[1]);
std::cout << std::setw(80) << data << std::endl;
return 0;
}
Poc:
poc.zip
To reproduce:
- Complie the drive program with ASAN:
$ g++ -fsanitize=address -g -o drive_prog drive_prog.cc
- Run
$ ./drive_prog poc.toml
ASAN says:
ubuntu@ubuntu:~/test/toml11$ ./drive_prog poc.toml
=================================================================
==2987781==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000008f at pc 0x5576fefc4e36 bp 0x7ffdd8515ce0 sp 0x7ffdd8515cd0
READ of size 1 at 0x60300000008f thread T0
#0 0x5576fefc4e35 in bool __gnu_cxx::__ops::_Iter_equals_val<char const>::operator()<__gnu_cxx::__normal_iterator<char const*, std::vector<char, std::allocator<char> > > >(__gnu_cxx::__normal_iterator<char const*, std::vector<char, std::allocator<char> > >) /usr/include/c++/9/bits/predefined_ops.h:241
#1 0x5576fef90808 in std::iterator_traits<__gnu_cxx::__normal_iterator<char const*, std::vector<char, std::allocator<char> > > >::difference_type std::__count_if<__gnu_cxx::__normal_iterator<char const*, std::vector<char, std::allocator<char> > >, __gnu_cxx::__ops::_Iter_equals_val<char const> >(__gnu_cxx::__normal_iterator<char const*, std::vector<char, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char const*, std::vector<char, std::allocator<char> > >, __gnu_cxx::__ops::_Iter_equals_val<char const>) /usr/include/c++/9/bits/stl_algo.h:3194
#2 0x5576fef6f7b3 in std::iterator_traits<__gnu_cxx::__normal_iterator<char const*, std::vector<char, std::allocator<char> > > >::difference_type std::count<__gnu_cxx::__normal_iterator<char const*, std::vector<char, std::allocator<char> > >, char>(__gnu_cxx::__normal_iterator<char const*, std::vector<char, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char const*, std::vector<char, std::allocator<char> > >, char const&) /usr/include/c++/9/bits/stl_algo.h:4121
#3 0x5576fef240f5 in toml::detail::location::reset(__gnu_cxx::__normal_iterator<char const*, std::vector<char, std::allocator<char> > >) toml/region.hpp:134
#4 0x5576fef482b6 in toml::detail::parse_literal_string[abi:cxx11](toml::detail::location&) toml/parser.hpp:698
#5 0x5576fef4a9cb in toml::detail::parse_string[abi:cxx11](toml::detail::location&) toml/parser.hpp:739
#6 0x5576fef89563 in toml::result<toml::basic_value<toml::discard_comments, std::unordered_map, std::vector>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > toml::detail::parse_value<toml::basic_value<toml::discard_comments, std::unordered_map, std::vector> >(toml::detail::location&) toml/parser.hpp:2051
#7 0x5576fefdb697 in toml::result<std::pair<std::pair<std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, toml::detail::region>, toml::basic_value<toml::discard_comments, std::unordered_map, std::vector> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > toml::detail::parse_key_value_pair<toml::basic_value<toml::discard_comments, std::unordered_map, std::vector> >(toml::detail::location&) toml/parser.hpp:1263
#8 0x5576fefb3e20 in toml::result<toml::basic_value<toml::discard_comments, std::unordered_map, std::vector>::table_type, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > toml::detail::parse_ml_table<toml::basic_value<toml::discard_comments, std::unordered_map, std::vector> >(toml::detail::location&) toml/parser.hpp:2222
#9 0x5576fef8c9ff in toml::result<toml::basic_value<toml::discard_comments, std::unordered_map, std::vector>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > toml::detail::parse_toml_file<toml::basic_value<toml::discard_comments, std::unordered_map, std::vector> >(toml::detail::location&) toml/parser.hpp:2326
#10 0x5576fefc35c7 in toml::basic_value<toml::discard_comments, std::unordered_map, std::vector> toml::parse<toml::discard_comments, std::unordered_map, std::vector>(std::istream&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) toml/parser.hpp:2430
#11 0x5576fef8f598 in toml::basic_value<toml::discard_comments, std::unordered_map, std::vector> toml::parse<toml::discard_comments, std::unordered_map, std::vector>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) toml/parser.hpp:2448
#12 0x5576fef21741 in main /home/ubuntu/test/toml11/drive_prog.cc:9
#13 0x7f7368844082 in __libc_start_main ../csu/libc-start.c:308
#14 0x5576fef214ad in _start (/home/ubuntu/test/toml11/drive_prog+0xe4ad)
0x60300000008f is located 0 bytes to the right of 31-byte region [0x603000000070,0x60300000008f)
allocated by thread T0 here:
#0 0x7f7368e6d587 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cc:104
#1 0x5576fefc7dfe in __gnu_cxx::new_allocator<char>::allocate(unsigned long, void const*) /usr/include/c++/9/ext/new_allocator.h:114
#2 0x5576fef93749 in std::allocator_traits<std::allocator<char> >::allocate(std::allocator<char>&, unsigned long) /usr/include/c++/9/bits/alloc_traits.h:443
#3 0x5576fefe6c4d in std::_Vector_base<char, std::allocator<char> >::_M_allocate(unsigned long) /usr/include/c++/9/bits/stl_vector.h:343
#4 0x5576ff02e972 in void std::vector<char, std::allocator<char> >::_M_range_initialize<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >(__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::forward_iterator_tag) /usr/include/c++/9/bits/stl_vector.h:1579
#5 0x5576ff023018 in std::vector<char, std::allocator<char> >::vector<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, void>(__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<char> const&) /usr/include/c++/9/bits/stl_vector.h:654
#6 0x5576ff0360dd in void __gnu_cxx::new_allocator<std::vector<char, std::allocator<char> > >::construct<std::vector<char, std::allocator<char> >, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >(std::vector<char, std::allocator<char> >*, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&&, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&&) /usr/include/c++/9/ext/new_allocator.h:146
#7 0x5576ff02ed9d in void std::allocator_traits<std::allocator<std::vector<char, std::allocator<char> > > >::construct<std::vector<char, std::allocator<char> >, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >(std::allocator<std::vector<char, std::allocator<char> > >&, std::vector<char, std::allocator<char> >*, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&&, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&&) /usr/include/c++/9/bits/alloc_traits.h:483
#8 0x5576ff023700 in std::_Sp_counted_ptr_inplace<std::vector<char, std::allocator<char> >, std::allocator<std::vector<char, std::allocator<char> > >, (__gnu_cxx::_Lock_policy)2>::_Sp_counted_ptr_inplace<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >(std::allocator<std::vector<char, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&&, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&&) /usr/include/c++/9/bits/shared_ptr_base.h:548
#9 0x5576ff013672 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<std::vector<char, std::allocator<char> >, std::allocator<std::vector<char, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >(std::vector<char, std::allocator<char> >*&, std::_Sp_alloc_shared_tag<std::allocator<std::vector<char, std::allocator<char> > > >, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&&, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&&) /usr/include/c++/9/bits/shared_ptr_base.h:679
#10 0x5576fefeec75 in std::__shared_ptr<std::vector<char, std::allocator<char> >, (__gnu_cxx::_Lock_policy)2>::__shared_ptr<std::allocator<std::vector<char, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >(std::_Sp_alloc_shared_tag<std::allocator<std::vector<char, std::allocator<char> > > >, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&&, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&&) /usr/include/c++/9/bits/shared_ptr_base.h:1344
#11 0x5576fefc4c40 in std::shared_ptr<std::vector<char, std::allocator<char> > >::shared_ptr<std::allocator<std::vector<char, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >(std::_Sp_alloc_shared_tag<std::allocator<std::vector<char, std::allocator<char> > > >, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&&, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&&) /usr/include/c++/9/bits/shared_ptr.h:359
#12 0x5576fef904a9 in std::shared_ptr<std::vector<char, std::allocator<char> > > std::allocate_shared<std::vector<char, std::allocator<char> >, std::allocator<std::vector<char, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >(std::allocator<std::vector<char, std::allocator<char> > > const&, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&&, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&&) /usr/include/c++/9/bits/shared_ptr.h:702
#13 0x5576fef6f2ff in std::shared_ptr<std::vector<char, std::allocator<char> > > std::make_shared<std::vector<char, std::allocator<char> >, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >(__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&&, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&&) /usr/include/c++/9/bits/shared_ptr.h:718
#14 0x5576fef2380c in toml::detail::location::location(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) toml/region.hpp:81
#15 0x5576fef4715d in toml::detail::parse_literal_string[abi:cxx11](toml::detail::location&) toml/parser.hpp:667
#16 0x5576fef4a9cb in toml::detail::parse_string[abi:cxx11](toml::detail::location&) toml/parser.hpp:739
#17 0x5576fef89563 in toml::result<toml::basic_value<toml::discard_comments, std::unordered_map, std::vector>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > toml::detail::parse_value<toml::basic_value<toml::discard_comments, std::unordered_map, std::vector> >(toml::detail::location&) toml/parser.hpp:2051
#18 0x5576fefdb697 in toml::result<std::pair<std::pair<std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, toml::detail::region>, toml::basic_value<toml::discard_comments, std::unordered_map, std::vector> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > toml::detail::parse_key_value_pair<toml::basic_value<toml::discard_comments, std::unordered_map, std::vector> >(toml::detail::location&) toml/parser.hpp:1263
#19 0x5576fefb3e20 in toml::result<toml::basic_value<toml::discard_comments, std::unordered_map, std::vector>::table_type, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > toml::detail::parse_ml_table<toml::basic_value<toml::discard_comments, std::unordered_map, std::vector> >(toml::detail::location&) toml/parser.hpp:2222
#20 0x5576fef8c9ff in toml::result<toml::basic_value<toml::discard_comments, std::unordered_map, std::vector>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > toml::detail::parse_toml_file<toml::basic_value<toml::discard_comments, std::unordered_map, std::vector> >(toml::detail::location&) toml/parser.hpp:2326
#21 0x5576fefc35c7 in toml::basic_value<toml::discard_comments, std::unordered_map, std::vector> toml::parse<toml::discard_comments, std::unordered_map, std::vector>(std::istream&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) toml/parser.hpp:2430
#22 0x5576fef8f598 in toml::basic_value<toml::discard_comments, std::unordered_map, std::vector> toml::parse<toml::discard_comments, std::unordered_map, std::vector>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) toml/parser.hpp:2448
#23 0x5576fef21741 in main /home/ubuntu/test/toml11/drive_prog.cc:9
#24 0x7f7368844082 in __libc_start_main ../csu/libc-start.c:308
SUMMARY: AddressSanitizer: heap-buffer-overflow /usr/include/c++/9/bits/predefined_ops.h:241 in bool __gnu_cxx::__ops::_Iter_equals_val<char const>::operator()<__gnu_cxx::__normal_iterator<char const*, std::vector<char, std::allocator<char> > > >(__gnu_cxx::__normal_iterator<char const*, std::vector<char, std::allocator<char> > >)
Shadow bytes around the buggy address:
0x0c067fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c067fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c067fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c067fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c067fff8000: fa fa 00 00 00 00 fa fa fd fd fd fd fa fa 00 00
=>0x0c067fff8010: 00[07]fa fa fd fd fd fd fa fa fd fd fd fd fa fa
0x0c067fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8060: 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
Shadow gap: cc
==2987781==ABORTING
I debugged it for a while, but I failed to fix it due to lack of knowledge about c++ std.😞
Here is the position which is trigged a heap-buffer-overflow issue:
I also trim the case so that it can be easy to debug.
Hope that helps.
Metadata
Metadata
Assignees
Labels
No labels