Skip to content

SegFault/out of bounds data in wasm::WasmBinaryReader::readNames #6672

@shinyano

Description

@shinyano

Hi,

I noticed that certain input file for wasm-opt with flag -O3 would cause warning:warning: data index out of bounds in name section and program received SIGSEGV. The output of gdb and Valgrind is attached.
Note that the input file was generated by AFL++ and was not validated.

Reproduce:

input file: wasm_oob.zip
command: bin/wasm-opt -O3 wasm_oob.wasm

GDB

(gdb) r
Starting program: /home/usan/meas/aflver/binaryen/bin/wasm-opt -O3 afl/opt_out_pp/default/crashes/id:000147,sig:11,src:009807,time:6097300,execs:5084365,op:havoc,rep:1
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
warning: data index out of bounds in name section, data subsection:  at index 127

Program received signal SIGSEGV, Segmentation fault.
wasm::WasmBinaryReader::readNames (this=0x7fffffffbfa0, payloadLen=<optimized out>)
    at /home/usan/meas/aflver/binaryen/src/wasm/wasm-binary.cpp:3687
3687	          wasm.dataSegments[i]->setExplicitName(name);
(gdb) bt
#0  wasm::WasmBinaryReader::readNames (this=0x7fffffffbfa0, payloadLen=<optimized out>)
    at /home/usan/meas/aflver/binaryen/src/wasm/wasm-binary.cpp:3687
#1  0x00007ffff751a033 in wasm::WasmBinaryReader::read (this=0x7fffffffbfa0)
    at /home/usan/meas/aflver/binaryen/src/wasm/wasm-binary.cpp:1833
#2  0x00007ffff7585e99 in wasm::ModuleReader::readBinaryData (this=this@entry=0x7fffffffdc60, 
    input=std::vector of length 1577, capacity 1577 = {...}, wasm=..., sourceMapFilename="")
    at /home/usan/meas/aflver/binaryen/src/wasm/wasm-io.cpp:77
#3  0x00007ffff75862ca in wasm::ModuleReader::readBinary (this=0x55555570bd50 <__afl_area_initial>, 
    this@entry=0x7fffffffdc60, 
    filename="afl/opt_out_pp/default/crashes/id:000147,sig:11,src:009807,time:6097300,execs:5084365,op:havoc,rep:1", wasm=..., sourceMapFilename="")
    at /home/usan/meas/aflver/binaryen/src/wasm/wasm-io.cpp:88
#4  0x00007ffff7586e51 in wasm::ModuleReader::read (this=0x55555570bd50 <__afl_area_initial>, 
    filename=..., wasm=..., sourceMapFilename=...)
    at /home/usan/meas/aflver/binaryen/src/wasm/wasm-io.cpp:111
#5  0x0000555555644896 in main (argc=3, argv=0x7fffffffdfa8)
    at /home/usan/meas/aflver/binaryen/src/tools/wasm-opt.cpp:292
(gdb) 

Valgrind:

warning: data index out of bounds in name section, data subsection:  at index 127
==13980== Invalid read of size 8
==13980==    at 0x58582B8: wasm::WasmBinaryReader::readNames(unsigned long) (in /home/usan/meas/aflver/binaryen/lib/libbinaryen.so)
==13980==    by 0x5843032: wasm::WasmBinaryReader::read() (in /home/usan/meas/aflver/binaryen/lib/libbinaryen.so)
==13980==    by 0x58AEE98: wasm::ModuleReader::readBinaryData(std::vector<char, std::allocator<char> >&, wasm::Module&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (in /home/usan/meas/aflver/binaryen/lib/libbinaryen.so)
==13980==    by 0x58AF2C9: wasm::ModuleReader::readBinary(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, wasm::Module&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (in /home/usan/meas/aflver/binaryen/lib/libbinaryen.so)
==13980==    by 0x58AFE50: wasm::ModuleReader::read(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, wasm::Module&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (in /home/usan/meas/aflver/binaryen/lib/libbinaryen.so)
==13980==    by 0x1F8895: main (in /home/usan/meas/aflver/binaryen/bin/wasm-opt)
==13980==  Address 0x69b1fb0 is 0 bytes after a block of size 16 alloc'd
==13980==    at 0x483BE63: operator new(unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==13980==    by 0x520F416: void std::vector<std::unique_ptr<wasm::DataSegment, std::default_delete<wasm::DataSegment> >, std::allocator<std::unique_ptr<wasm::DataSegment, std::default_delete<wasm::DataSegment> > > >::_M_realloc_insert<std::unique_ptr<wasm::DataSegment, std::default_delete<wasm::DataSegment> > >(__gnu_cxx::__normal_iterator<std::unique_ptr<wasm::DataSegment, std::default_delete<wasm::DataSegment> >*, std::vector<std::unique_ptr<wasm::DataSegment, std::default_delete<wasm::DataSegment> >, std::allocator<std::unique_ptr<wasm::DataSegment, std::default_delete<wasm::DataSegment> > > > >, std::unique_ptr<wasm::DataSegment, std::default_delete<wasm::DataSegment> >&&) (in /home/usan/meas/aflver/binaryen/lib/libbinaryen.so)
==13980==    by 0x58156E5: wasm::DataSegment* wasm::addModuleElement<std::vector<std::unique_ptr<wasm::DataSegment, std::default_delete<wasm::DataSegment> >, std::allocator<std::unique_ptr<wasm::DataSegment, std::default_delete<wasm::DataSegment> > > >, std::unordered_map<wasm::Name, wasm::DataSegment*, std::hash<wasm::Name>, std::equal_to<wasm::Name>, std::allocator<std::pair<wasm::Name const, wasm::DataSegment*> > >, wasm::DataSegment>(std::vector<std::unique_ptr<wasm::DataSegment, std::default_delete<wasm::DataSegment> >, std::allocator<std::unique_ptr<wasm::DataSegment, std::default_delete<wasm::DataSegment> > > >&, std::unordered_map<wasm::Name, wasm::DataSegment*, std::hash<wasm::Name>, std::equal_to<wasm::Name>, std::allocator<std::pair<wasm::Name const, wasm::DataSegment*> > >&, std::unique_ptr<wasm::DataSegment, std::default_delete<wasm::DataSegment> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (in /home/usan/meas/aflver/binaryen/lib/libbinaryen.so)
==13980==    by 0x5815292: wasm::Module::addDataSegment(std::unique_ptr<wasm::DataSegment, std::default_delete<wasm::DataSegment> >&&) (in /home/usan/meas/aflver/binaryen/lib/libbinaryen.so)
==13980==    by 0x5850966: wasm::WasmBinaryReader::readDataSegments() (in /home/usan/meas/aflver/binaryen/lib/libbinaryen.so)
==13980==    by 0x58435A0: wasm::WasmBinaryReader::read() (in /home/usan/meas/aflver/binaryen/lib/libbinaryen.so)
==13980==    by 0x58AEE98: wasm::ModuleReader::readBinaryData(std::vector<char, std::allocator<char> >&, wasm::Module&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (in /home/usan/meas/aflver/binaryen/lib/libbinaryen.so)
==13980==    by 0x58AF2C9: wasm::ModuleReader::readBinary(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, wasm::Module&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (in /home/usan/meas/aflver/binaryen/lib/libbinaryen.so)
==13980==    by 0x58AFE50: wasm::ModuleReader::read(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, wasm::Module&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (in /home/usan/meas/aflver/binaryen/lib/libbinaryen.so)
==13980==    by 0x1F8895: main (in /home/usan/meas/aflver/binaryen/bin/wasm-opt)
==13980== 
==13980== Invalid write of size 8
==13980==    at 0x58582BC: wasm::WasmBinaryReader::readNames(unsigned long) (in /home/usan/meas/aflver/binaryen/lib/libbinaryen.so)
==13980==    by 0x5843032: wasm::WasmBinaryReader::read() (in /home/usan/meas/aflver/binaryen/lib/libbinaryen.so)
==13980==    by 0x58AEE98: wasm::ModuleReader::readBinaryData(std::vector<char, std::allocator<char> >&, wasm::Module&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (in /home/usan/meas/aflver/binaryen/lib/libbinaryen.so)
==13980==    by 0x58AF2C9: wasm::ModuleReader::readBinary(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, wasm::Module&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (in /home/usan/meas/aflver/binaryen/lib/libbinaryen.so)
==13980==    by 0x58AFE50: wasm::ModuleReader::read(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, wasm::Module&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (in /home/usan/meas/aflver/binaryen/lib/libbinaryen.so)
==13980==    by 0x1F8895: main (in /home/usan/meas/aflver/binaryen/bin/wasm-opt)
==13980==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==13980== 
==13980== 
==13980== Process terminating with default action of signal 11 (SIGSEGV)
==13980==  Access not within mapped region at address 0x0
==13980==    at 0x58582BC: wasm::WasmBinaryReader::readNames(unsigned long) (in /home/usan/meas/aflver/binaryen/lib/libbinaryen.so)
==13980==    by 0x5843032: wasm::WasmBinaryReader::read() (in /home/usan/meas/aflver/binaryen/lib/libbinaryen.so)
==13980==    by 0x58AEE98: wasm::ModuleReader::readBinaryData(std::vector<char, std::allocator<char> >&, wasm::Module&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (in /home/usan/meas/aflver/binaryen/lib/libbinaryen.so)
==13980==    by 0x58AF2C9: wasm::ModuleReader::readBinary(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, wasm::Module&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (in /home/usan/meas/aflver/binaryen/lib/libbinaryen.so)
==13980==    by 0x58AFE50: wasm::ModuleReader::read(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, wasm::Module&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (in /home/usan/meas/aflver/binaryen/lib/libbinaryen.so)
==13980==    by 0x1F8895: main (in /home/usan/meas/aflver/binaryen/bin/wasm-opt)
==13980==  If you believe this happened as a result of a stack
==13980==  overflow in your program's main thread (unlikely but
==13980==  possible), you can try to increase the size of the
==13980==  main thread stack using the --main-stacksize= flag.
==13980==  The main thread stack size used in this run was 8388608.
==13980== 
==13980== HEAP SUMMARY:
==13980==     in use at exit: 208,102 bytes in 2,481 blocks
==13980==   total heap usage: 4,012 allocs, 1,531 frees, 435,858 bytes allocated
==13980== 
==13980== LEAK SUMMARY:
==13980==    definitely lost: 0 bytes in 0 blocks
==13980==    indirectly lost: 0 bytes in 0 blocks
==13980==      possibly lost: 0 bytes in 0 blocks
==13980==    still reachable: 208,102 bytes in 2,481 blocks
==13980==         suppressed: 0 bytes in 0 blocks
==13980== Rerun with --leak-check=full to see details of leaked memory
==13980== 
==13980== For lists of detected and suppressed errors, rerun with: -s
==13980== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Segmentation fault

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions