serge1 / ELFIO

ELFIO - ELF (Executable and Linkable Format) reader and producer implemented as a header only C++ library
http://serge1.github.io/ELFIO
MIT License
720 stars 155 forks source link

segmentation fault in example/elfdump #36

Closed orbitcowboy closed 4 years ago

orbitcowboy commented 5 years ago

I was able to crash the example/elfdump with an invalid input (generated by afl-fuzz):

The file is available at https://filebin.ca/4rhvxKnzKdGt/test

$ ./elfdump test > /dev/null
Segmentation fault
$

gdb backtrace

backtrace:
#0  __memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:440
No locals.
#1  0x00007ffff7f0666c in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_mutate(unsigned long, unsigned long, char const*, unsigned long) () from /lib/x86_64-linux-gnu/libstdc++.so.6
No symbol table info available.
#2  0x00007ffff7f073f1 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_replace(unsigned long, unsigned long, char const*, unsigned long) () from /lib/x86_64-linux-gnu/libstdc++.so.6
No symbol table info available.
#3  0x0000000000407704 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::assign (__s=0x45452c "GNU", __n=4294967295, this=<optimized out>) at /bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/basic_string.h:1422
No locals.
#4  ELFIO::note_section_accessor_template<ELFIO::section>::get_note (this=<optimized out>, index=<optimized out>, type=<optimized out>, name=..., desc=<optimized out>, descSize=<optimized out>) at ../../elfio/elfio_note.hpp:83
        align = 4
        convertor = <optimized out>
        namesz = <optimized out>
        max_name_size = <optimized out>
        pData = <optimized out>
#5  ELFIO::dump::notes (out=..., reader=...) at ../../elfio/elfio_dump.hpp:693
        type = 1
        name = <optimized out>
        desc = <optimized out>
        descsz = <optimized out>
        j = 0
        notes = {elf_file = @0x7fffffffdd68, note_section = 0x454450, note_start_positions = std::vector of length 1, capacity 1 = {0}}
        no_notes = <optimized out>
        sec = <optimized out>
        i = 2
        no = <optimized out>
#6  0x0000000000402917 in main (argc=<optimized out>, argv=0x7fffffffdef8) at elfdump.cpp:53
        reader = {sections = {parent = 0x7fffffffdd68}, segments = {parent = 0x7fffffffdd68}, header = 0x454280, sections_ = std::vector of length 41, capacity 64 = {0x4542e0, 0x454380, 0x454450, 0x454550, 0x454840, 0x454940, 0x4550d0, 0x455930, 0x455a70, 0x455c10, 0x455dd0, 0x456440, 0x4564e0, 0x456970, 0x456a10, 0x456ab0, 0x458c20, 0x4595f0, 0x45b510, 0x45c5a0, 0x45c640, 0x45c6e0, 0x45c780, 0x45ca40, 0x45cd10, 0x45cde0, 0x45d090, 0x45e3b0, 0x45e450, 0x45e590, 0x4661a0, 0x466240, 0x466bf0, 0x477320, 0x48c9c0, 0x48ca60, 0x48cb20, 0x48ea30, 0x49c790, 0x49f510, 0x4a4a70}, segments_ = std::vector of length 12, capacity 16 = {0x451f70, 0x451ec0, 0x4a5020, 0x4a6dc0, 0x4a6e50, 0x4ac610, 0x4adfc0, 0x4ae280, 0x4ae340, 0x4ae480, 0x4aed50, 0x4aede0}, convertor = {need_conversion = false}, current_file_pos = 0}

registers:
rax            0x7ffef79bf010      140733052612624
rbx            0x7fffffffdd00      140737488346368
rcx            0x7ffef79bf010      140733052612624
rdx            0xffffffff          4294967295
rsi            0x45452c            4539692
rdi            0x7ffef79bf010      140733052612624
rbp            0x0                 0x0
rsp            0x7fffffffdbe8      0x7fffffffdbe8
r8             0xffffffff          4294967295
r9             0x45452c            4539692
r10            0x22                34
r11            0x246               582
r12            0x7fffffffdd10      140737488346384
r13            0x0                 0
r14            0xffffffff          4294967295
r15            0x7ffef79bf010      140733052612624
rip            0x7ffff7bfe2a4      0x7ffff7bfe2a4 <__memmove_avx_unaligned_erms+548>
eflags         0x10216             [ PF AF IF RF ]
cs             0x33                51
ss             0x2b                43
ds             0x0                 0
es             0x0                 0
fs             0x0                 0
gs             0x0                 0

current instructions:
=> 0x7ffff7bfe2a4 <__memmove_avx_unaligned_erms+548>:   vmovdqu -0x20(%rsi,%rdx,1),%ymm8
   0x7ffff7bfe2aa <__memmove_avx_unaligned_erms+554>:   lea    -0x20(%rdi,%rdx,1),%r11
   0x7ffff7bfe2af <__memmove_avx_unaligned_erms+559>:   lea    -0x20(%rsi,%rdx,1),%rcx
   0x7ffff7bfe2b4 <__memmove_avx_unaligned_erms+564>:   mov    %r11,%r9
   0x7ffff7bfe2b7 <__memmove_avx_unaligned_erms+567>:   mov    %r11,%r8
   0x7ffff7bfe2ba <__memmove_avx_unaligned_erms+570>:   and    $0x1f,%r8
   0x7ffff7bfe2be <__memmove_avx_unaligned_erms+574>:   sub    %r8,%rcx
   0x7ffff7bfe2c1 <__memmove_avx_unaligned_erms+577>:   sub    %r8,%r9
   0x7ffff7bfe2c4 <__memmove_avx_unaligned_erms+580>:   sub    %r8,%rdx
   0x7ffff7bfe2c7 <__memmove_avx_unaligned_erms+583>:   cmp    0x60e8a(%rip),%rdx        # 0x7ffff7c5f158 <__x86_shared_non_temporal_threshold>
   0x7ffff7bfe2ce <__memmove_avx_unaligned_erms+590>:   ja     0x7ffff7bfe3c4 <__memmove_avx_unaligned_erms+836>
   0x7ffff7bfe2d4 <__memmove_avx_unaligned_erms+596>:   vmovdqu (%rcx),%ymm0
   0x7ffff7bfe2d8 <__memmove_avx_unaligned_erms+600>:   vmovdqu -0x20(%rcx),%ymm1
   0x7ffff7bfe2dd <__memmove_avx_unaligned_erms+605>:   vmovdqu -0x40(%rcx),%ymm2
   0x7ffff7bfe2e2 <__memmove_avx_unaligned_erms+610>:   vmovdqu -0x60(%rcx),%ymm3
   0x7ffff7bfe2e7 <__memmove_avx_unaligned_erms+615>:   sub    $0x80,%rcx

threads backtrace:

Thread 1 (process 77605):
#0  __memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:440
#1  0x00007ffff7f0666c in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_mutate(unsigned long, unsigned long, char const*, unsigned long) () from /lib/x86_64-linux-gnu/libstdc++.so.6
#2  0x00007ffff7f073f1 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_replace(unsigned long, unsigned long, char const*, unsigned long) () from /lib/x86_64-linux-gnu/libstdc++.so.6
#3  0x0000000000407704 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::assign (__s=0x45452c "GNU", __n=4294967295, this=<optimized out>) at /bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/basic_string.h:1422
#4  ELFIO::note_section_accessor_template<ELFIO::section>::get_note (this=<optimized out>, index=<optimized out>, type=<optimized out>, name=..., desc=<optimized out>, descSize=<optimized out>) at ../../elfio/elfio_note.hpp:83
#5  ELFIO::dump::notes (out=..., reader=...) at ../../elfio/elfio_dump.hpp:693
#6  0x0000000000402917 in main (argc=<optimized out>, argv=0x7fffffffdef8) at elfdump.cpp:53
serge1 commented 4 years ago

The .note section of this file is corrupted. 'readelf' gives the following message: "readelf: Warning: Corrupt note: only 4 bytes remain, not enough for a full note". Commit 4539293 tries to prevent crash for this specific case. Best regards, Serge

orbitcowboy commented 4 years ago

Cool! Thanks for fixing this issue.