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

fileinfo crashes in fileformat::ElfFormat::loadInfoFromDynamicTables() #89

Closed
bansan85 opened this issue Jan 14, 2018 · 3 comments
Closed

Comments

@bansan85
Copy link

fileinfo crashes while loading dynamic table.
Found with fuzzer after a dozen of second.

Input

loadDynamicTable.zip

fileinfo loadDynamicTable

output

backtrace:

#0  __memmove_sse2_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:356
#1  0x0000555555caa806 in std::__copy_move<false, true, std::random_access_iterator_tag>::__copy_m<char> (__result=<optimized out>, __last=<optimized out>, 
    __first=<optimized out>) at /usr/lib/gcc/x86_64-pc-linux-gnu/7.2.0/include/g++-v7/bits/stl_algobase.h:368
#2  std::__copy_move_a<false, char const*, char*> (__result=<optimized out>, __last=<optimized out>, __first=<optimized out>)
    at /usr/lib/gcc/x86_64-pc-linux-gnu/7.2.0/include/g++-v7/bits/stl_algobase.h:386
#3  std::__copy_move_a2<false, char const*, char*> (__result=<optimized out>, __last=<optimized out>, __first=<optimized out>)
    at /usr/lib/gcc/x86_64-pc-linux-gnu/7.2.0/include/g++-v7/bits/stl_algobase.h:424
#4  std::copy<char const*, char*> (__result=<optimized out>, __last=0x230 <error: Cannot access memory at address 0x230>, 
    __first=0x200 <error: Cannot access memory at address 0x200>) at /usr/lib/gcc/x86_64-pc-linux-gnu/7.2.0/include/g++-v7/bits/stl_algobase.h:456
#5  ELFIO::section_impl<ELFIO::Elf64_Shdr>::set_data (this=0x5555576786b0, raw_data=0x200 <error: Cannot access memory at address 0x200>, size=48)
    at /home/legarrec/info/programmation/retdec/deps/fileformat/deps/elfio/include/elfio/elfio_section.hpp:173
#6  0x0000555555c8d6fe in fileformat::ElfFormat::addStringTable (this=this@entry=0x555557670510, dynamicSection=dynamicSection@entry=0x555557678540, 
    table=...) at /home/legarrec/info/programmation/retdec/deps/fileformat/src/fileformat/file_format/elf/elf_format.cpp:1160
#7  0x0000555555c9eeb0 in fileformat::ElfFormat::loadInfoFromDynamicTables (this=this@entry=0x555557670510, noOfTables=noOfTables@entry=1)
    at /home/legarrec/info/programmation/retdec/deps/fileformat/src/fileformat/file_format/elf/elf_format.cpp:1949
#8  0x0000555555c9fe3f in fileformat::ElfFormat::loadInfoFromDynamicSegment (this=this@entry=0x555557670510)
    at /home/legarrec/info/programmation/retdec/deps/fileformat/src/fileformat/file_format/elf/elf_format.cpp:2010
#9  0x0000555555ca0740 in fileformat::ElfFormat::initStructures (this=this@entry=0x555557670510)
    at /home/legarrec/info/programmation/retdec/deps/fileformat/src/fileformat/file_format/elf/elf_format.cpp:1089
#10 0x0000555555ca26e8 in fileformat::ElfFormat::initStructures (this=0x555557670510)
    at /home/legarrec/info/programmation/retdec/deps/fileformat/src/fileformat/file_format/elf/elf_format.cpp:1074
#11 fileformat::ElfFormat::ElfFormat (this=0x555557670510, pathToFile=..., loadFlags=<optimized out>)
    at /home/legarrec/info/programmation/retdec/deps/fileformat/src/fileformat/file_format/elf/elf_format.cpp:1031
#12 0x000055555599169a in fileinfo::ElfWrapper::ElfWrapper (this=0x555557670510, pathToFile=..., loadFlags=fileformat::NONE)
    at /home/legarrec/info/programmation/retdec/deps/fileformat/src/fileinfo/file_wrapper/elf_wrapper.cpp:18
#13 0x0000555555668c47 in __gnu_cxx::new_allocator<fileinfo::ElfWrapper>::construct<fileinfo::ElfWrapper, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, fileformat::LoadFlags&> (this=<optimized out>, __p=0x555557670510)
    at /usr/lib/gcc/x86_64-pc-linux-gnu/7.2.0/include/g++-v7/ext/new_allocator.h:136
#14 std::allocator_traits<std::allocator<fileinfo::ElfWrapper> >::construct<fileinfo::ElfWrapper, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, fileformat::LoadFlags&> (__a=..., __p=<optimized out>) at /usr/lib/gcc/x86_64-pc-linux-gnu/7.2.0/include/g++-v7/bits/alloc_traits.h:475
#15 std::_Sp_counted_ptr_inplace<fileinfo::ElfWrapper, std::allocator<fileinfo::ElfWrapper>, (__gnu_cxx::_Lock_policy)2>::_Sp_counted_ptr_inplace<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, fileformat::LoadFlags&> (__a=..., this=0x555557670500)
    at /usr/lib/gcc/x86_64-pc-linux-gnu/7.2.0/include/g++-v7/bits/shared_ptr_base.h:526
#16 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<fileinfo::ElfWrapper, std::allocator<fileinfo::ElfWrapper>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, fileformat::LoadFlags&> (__a=..., this=<optimized out>)
    at /usr/lib/gcc/x86_64-pc-linux-gnu/7.2.0/include/g++-v7/bits/shared_ptr_base.h:637
#17 std::__shared_ptr<fileinfo::ElfWrapper, (__gnu_cxx::_Lock_policy)2>::__shared_ptr<std::allocator<fileinfo::ElfWrapper>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, fileformat::LoadFlags&> (__a=..., __tag=..., this=<optimized out>)
    at /usr/lib/gcc/x86_64-pc-linux-gnu/7.2.0/include/g++-v7/bits/shared_ptr_base.h:1295
#18 std::shared_ptr<fileinfo::ElfWrapper>::shared_ptr<std::allocator<fileinfo::ElfWrapper>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, fileformat::LoadFlags&> (__a=..., __tag=..., this=<optimized out>)
    at /usr/lib/gcc/x86_64-pc-linux-gnu/7.2.0/include/g++-v7/bits/shared_ptr.h:344
#19 std::allocate_shared<fileinfo::ElfWrapper, std::allocator<fileinfo::ElfWrapper>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, fileformat::LoadFlags&> (__a=...) at /usr/lib/gcc/x86_64-pc-linux-gnu/7.2.0/include/g++-v7/bits/shared_ptr.h:691
#20 std::make_shared<fileinfo::ElfWrapper, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, fileformat::LoadFlags&> ()
    at /usr/lib/gcc/x86_64-pc-linux-gnu/7.2.0/include/g++-v7/bits/shared_ptr.h:707
#21 fileinfo::ElfDetector::ElfDetector (this=0x555557670160, pathToInputFile=..., finfo=..., searchPar=..., loadFlags=fileformat::NONE)
    at /home/legarrec/info/programmation/retdec/deps/fileformat/src/fileinfo/file_detector/elf_detector.cpp:399
#22 0x0000555555646125 in fileinfo::createFileDetector (pathToInputFile=..., fileFormat=<optimized out>, finfo=..., searchPar=..., loadFlags=fileformat::NONE)
    at /home/legarrec/info/programmation/retdec/deps/fileformat/src/fileinfo/file_detector/detector_factory.cpp:38
#23 0x000055555560a593 in main (argc=<optimized out>, argv=<optimized out>)
    at /home/legarrec/info/programmation/retdec/deps/fileformat/src/fileinfo/fileinfo.cpp:395

From master (8c4b23d)

@s3rvac
Copy link
Member

s3rvac commented Jan 15, 2018

Thank you for the report. I can confirm that fileinfo crashes when analyzing the attached ELF file.

Output from valgrind:

[Several "Conditional jump or move depends on uninitialised value(s)" errors]
...

Invalid read of size 8
   at 0x4C33C30: memmove (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
   by 0x26B4A3: char* std::__copy_move<...>::__copy_m<char>(char const*, char const*, char*) (stl_algobase.h:368)
   by 0x26B17B: char* std::__copy_move_a<...>(char const*, char const*, char*) (stl_algobase.h:386)
   by 0x26B6AE: char* std::__copy_move_a2<...>(char const*, char const*, char*) (stl_algobase.h:424)
   by 0x26B458: char* std::copy<...>(char const*, char const*, char*) (stl_algobase.h:456)
   by 0x343D30: ELFIO::section_impl<ELFIO::Elf64_Shdr>::set_data(char const*, unsigned int) (elfio_section.hpp:173)
   by 0x32F04F: fileformat::ElfFormat::addStringTable(ELFIO::section*, fileformat::DynamicTable const&) (elf_format.cpp:1160)
   by 0x33323D: fileformat::ElfFormat::loadInfoFromDynamicTables(unsigned long) (elf_format.cpp:1949)
   by 0x33380C: fileformat::ElfFormat::loadInfoFromDynamicSegment() (elf_format.cpp:2010)
   by 0x32EAA2: fileformat::ElfFormat::initStructures() (elf_format.cpp:1089)
   by 0x32E6DD: fileformat::ElfFormat::ElfFormat(...) (elf_format.cpp:1031)
   by 0x239E2D: fileinfo::ElfWrapper::ElfWrapper(...) (elf_wrapper.cpp:18)
 Address 0x200 is not stack'd, malloc'd or (recently) free'd

@s3rvac s3rvac changed the title SIG in ElfFormat::loadDynamicTable fileinfo crashes in fileformat::ElfFormat::loadInfoFromDynamicTables() Jan 15, 2018
@s3rvac
Copy link
Member

s3rvac commented Jan 15, 2018

More files for which fileinfo crashes inside fileformat::ElfFormat::loadInfoFromDynamicTables():

The output from valgrind slightly differs from the originally reported case:

Invalid read of size 8
   at 0x33338C: fileformat::ElfFormat::loadInfoFromDynamicTables(unsigned long) (elf_format.cpp:1974)
   by 0x33380C: fileformat::ElfFormat::loadInfoFromDynamicSegment() (elf_format.cpp:2010)
   by 0x32EAA2: fileformat::ElfFormat::initStructures() (elf_format.cpp:1089)
   by 0x32E6DD: fileformat::ElfFormat::ElfFormat(...) (elf_format.cpp:1031)
   by 0x239E2D: fileinfo::ElfWrapper::ElfWrapper(...) (elf_wrapper.cpp:18)
   by 0x1B5DE9: void __gnu_cxx::new_allocator<...>::construct<...>(...) (new_allocator.h:136)
   by 0x1B5CA3: void std::allocator_traits<...>::construct<...>(...) (alloc_traits.h:475)
   by 0x1B5AE6: std::_Sp_counted_ptr_inplace<...>::_Sp_counted_ptr_inplace<...>(...) (shared_ptr_base.h:526)
   by 0x1B582E: std::__shared_count<...>::__shared_count<...>(...) (shared_ptr_base.h:637)
   by 0x1B563D: std::__shared_ptr<...>::__shared_ptr<...>(...) (shared_ptr_base.h:1295)
   by 0x1B54B4: std::shared_ptr<...>::shared_ptr<...>(...) (shared_ptr.h:344)
   by 0x1B52AD: std::shared_ptr<...> std::allocate_shared<...>(...) (shared_ptr.h:691)
 Address 0xfffffffffffffff8 is not stack'd, malloc'd or (recently) free'd

I have investigated the above cases. In fileformat/file_format/elf/elf_format.cpp, there is the following code:

1971  auto *got = addGlobalOffsetTable(sec, *dynTab);
1972  if(got)
1973  {
1974      auto *symbols = symbolTables.back();
1975      loadSymbols(*symbols, *dynTab, *got);
1976  }

In line 1974, symbolTables is empty, so calling back() on it results in an invalid-memory access.

In the originally reported case, fileinfo fails inside fileformat::ElfFormat::addStringTable(), which is a different place. However, since all crashes happen inside fileformat::ElfFormat::loadInfoFromDynamicTables(), all of them are reported in this issue as they are probably related.

@mbandzi
Copy link
Contributor

mbandzi commented Mar 2, 2018

These were actually multiple problems on several places, fixed in d109064491ea

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

No branches or pull requests

3 participants