WebAssembly / binaryen

Optimizer and compiler/toolchain library for WebAssembly
Apache License 2.0
7.46k stars 740 forks source link

Abort in `wasm-reduce` under `wasm::WasmBinaryBuilder::getType` #2650

Open fitzgen opened 4 years ago

fitzgen commented 4 years ago

Steps to Reproduce

$ wasm-reduce \
    -cmd ./predicate.sh \
    -t multi-val-overflow.test.wasm \
    -w multi-val-overflow.working.wasm \
    -b ~/binaryen/bin \
    multi-val-overflow.wasm \
    --debug --verbose --force

multi-val-overflow.wasm is this file: https://github.com/bytecodealliance/wasmparser/files/4171056/foo.wasm.2.gz

Here is predicate.sh Note that this scripte requires a rust toolchain and check out of https://github.com/bytecodealliance/wasmparser/ ```sh #!/usr/bin/env bash set -eux cargo run \ --manifest-path ~/wasmparser/Cargo.toml \ --example validate \ ~/scratch/multi-val-overflow.test.wasm \ 2>&1 | grep -q 'attempt to subtract with overflow' ```

Full Logs and Stacktrace

``` $ gdb wasm-reduce GNU gdb (GDB) 8.1.50.20180514-git Copyright (C) 2018 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-pc-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: . Find the GDB manual and other documentation resources online at: . For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from wasm-reduce...(no debugging symbols found)...done. (gdb) run -cmd ./predicate.sh -t multi-val-overflow.test.wasm -w multi-val-overflow.working.wasm -b ~/binaryen/bin multi-val-overflow.wasm --debug --verbose --force Starting program: /usr/local/bin/wasm-reduce -cmd ./predicate.sh -t multi-val-overflow.test.wasm -w multi-val-overflow.working.wasm -b ~/binaryen/bin multi-val-overflow.wasm --debug --verbose --force [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". |wasm-reduce |input: multi-val-overflow.wasm |test: multi-val-overflow.test.wasm |working: multi-val-overflow.working.wasm |bin dir: /home/fitzgen/binaryen/bin/ [Detaching after fork from child process 16320] [Detaching after fork from child process 16329] |expected result: [ProgramResult] code: 0 stdout: [====] in 0.0598609 seconds [/ProgramResult] |!! Make sure the above is what you expect! !! |checking that command has different behavior on invalid binary (this verifies that the test file is used by the command) [Detaching after fork from child process 16335] [Detaching after fork from child process 16342] |checking that command has expected behavior on canonicalized (read-written) binary [Detaching after fork from child process 16349] [Detaching after fork from child process 16352] |! failed to read and write the binary [ProgramResult] code: 256 stdout: [====] in 0.00319539 seconds [/ProgramResult] |input size: 145 |starting reduction! | reduce using passes... [Detaching after fork from child process 16355] [Detaching after fork from child process 16358] [Detaching after fork from child process 16362] [Detaching after fork from child process 16365] [Detaching after fork from child process 16368] [Detaching after fork from child process 16371] [Detaching after fork from child process 16374] [Detaching after fork from child process 16377] [Detaching after fork from child process 16380] [Detaching after fork from child process 16383] [Detaching after fork from child process 16386] [Detaching after fork from child process 16389] [Detaching after fork from child process 16392] [Detaching after fork from child process 16395] [Detaching after fork from child process 16398] [Detaching after fork from child process 16401] [Detaching after fork from child process 16404] [Detaching after fork from child process 16407] [Detaching after fork from child process 16410] [Detaching after fork from child process 16413] [Detaching after fork from child process 16416] [Detaching after fork from child process 16419] [Detaching after fork from child process 16422] [Detaching after fork from child process 16425] [Detaching after fork from child process 16428] [Detaching after fork from child process 16431] [Detaching after fork from child process 16434] [Detaching after fork from child process 16437] [Detaching after fork from child process 16440] [Detaching after fork from child process 16443] [Detaching after fork from child process 16446] [Detaching after fork from child process 16449] [Detaching after fork from child process 16452] [Detaching after fork from child process 16455] [Detaching after fork from child process 16458] [Detaching after fork from child process 16461] [Detaching after fork from child process 16464] [Detaching after fork from child process 16467] [Detaching after fork from child process 16470] [Detaching after fork from child process 16473] [Detaching after fork from child process 16476] [Detaching after fork from child process 16479] [Detaching after fork from child process 16482] [Detaching after fork from child process 16485] [Detaching after fork from child process 16488] [Detaching after fork from child process 16491] [Detaching after fork from child process 16494] [Detaching after fork from child process 16497] [Detaching after fork from child process 16500] [Detaching after fork from child process 16503] [Detaching after fork from child process 16506] [Detaching after fork from child process 16509] [Detaching after fork from child process 16512] [Detaching after fork from child process 16515] [Detaching after fork from child process 16518] [Detaching after fork from child process 16521] [Detaching after fork from child process 16524] [Detaching after fork from child process 16527] | after pass reduction: 145 | pass progress: 0, last destructive: 0 | progress is good, do not quickly decrease factor | reduce destructively... (factor: 36) terminate called after throwing an instance of 'wasm::ParseException' Program received signal SIGABRT, Aborted. 0x00007ffff6ec4e97 in raise () from /lib/x86_64-linux-gnu/libc.so.6 (gdb) bt #0 0x00007ffff6ec4e97 in raise () from /lib/x86_64-linux-gnu/libc.so.6 #1 0x00007ffff6ec6801 in abort () from /lib/x86_64-linux-gnu/libc.so.6 #2 0x00007ffff7ad8957 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #3 0x00007ffff7adeab6 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #4 0x00007ffff7adeaf1 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #5 0x00007ffff7aded24 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #6 0x000055555599a2b3 in wasm::WasmBinaryBuilder::throwError(std::__cxx11::basic_string, std::allocator >) () #7 0x000055555599bc2c in wasm::WasmBinaryBuilder::getType() () #8 0x00005555559b2976 in wasm::WasmBinaryBuilder::visitBlock(wasm::Block*) () #9 0x00005555559b095e in wasm::WasmBinaryBuilder::readExpression(wasm::Expression*&) () #10 0x00005555559b144a in wasm::WasmBinaryBuilder::skipUnreachableCode() () #11 0x00005555559b1708 in wasm::WasmBinaryBuilder::processExpressions() () #12 0x00005555559b2e4d in wasm::WasmBinaryBuilder::getBlockOrSingleton(wasm::Type, unsigned int) () #13 0x00005555559b35e4 in wasm::WasmBinaryBuilder::readFunctions() () #14 0x00005555559b4358 in wasm::WasmBinaryBuilder::read() () #15 0x00005555559da81a in wasm::readBinaryData(std::vector >&, wasm::Module&, std::__cxx11::basic_string, std::allocator >) () #16 0x00005555559dac79 in wasm::ModuleReader::readBinary(std::__cxx11::basic_string, std::allocator >, wasm::Module&, std::__cxx11::basic_string, std::allocator >) () #17 0x00005555559dba38 in wasm::ModuleReader::read(std::__cxx11::basic_string, std::allocator >, wasm::Module&, std::__cxx11::basic_string, std::allocator >) () #18 0x00005555556c9b09 in main () (gdb) ```
fitzgen commented 4 years ago

Just pulled master and tried again with commit 7168130594a226b6a48186a7c1dd68987f2007cf and got this different abort and stacktrace:

``` $ gdb wasm-reduce GNU gdb (GDB) 8.1.50.20180514-git Copyright (C) 2018 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-pc-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: . Find the GDB manual and other documentation resources online at: . For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from wasm-reduce...(no debugging symbols found)...done. (gdb) run -cmd ./predicate.sh -t multi-val-overflow.test.wasm -w multi-val-overflow.working.wasm -b ~/binaryen/bin multi-val-overflow.wasm --debug --verbose --force Starting program: /usr/local/bin/wasm-reduce -cmd ./predicate.sh -t multi-val-overflow.test.wasm -w multi-val-overflow.working.wasm -b ~/binaryen/bin multi-val-overflow.wasm --debug --verbose --force [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". |wasm-reduce |input: multi-val-overflow.wasm |test: multi-val-overflow.test.wasm |working: multi-val-overflow.working.wasm |bin dir: /home/fitzgen/binaryen/bin/ [Detaching after fork from child process 18001] [Detaching after fork from child process 18004] |expected result: [ProgramResult] code: 32512 stdout: [====] in 0.0036857 seconds [/ProgramResult] |!! Make sure the above is what you expect! !! |checking that command has different behavior on invalid binary (this verifies that the test file is used by the command) [Detaching after fork from child process 18007] [Detaching after fork from child process 18010] |! running command on an invalid module should give different results [ProgramResult] code: 32512 stdout: [====] in 0.00237007 seconds [/ProgramResult] |checking that command has expected behavior on canonicalized (read-written) binary [Detaching after fork from child process 18013] [Detaching after fork from child process 18016] |! failed to read and write the binary [ProgramResult] code: 256 stdout: [====] in 0.00304421 seconds [/ProgramResult] |input size: 0 |starting reduction! | reduce using passes... [Detaching after fork from child process 18019] [Detaching after fork from child process 18022] [Detaching after fork from child process 18025] [Detaching after fork from child process 18028] [Detaching after fork from child process 18031] [Detaching after fork from child process 18034] [Detaching after fork from child process 18037] [Detaching after fork from child process 18040] [Detaching after fork from child process 18043] [Detaching after fork from child process 18046] [Detaching after fork from child process 18049] [Detaching after fork from child process 18052] [Detaching after fork from child process 18055] [Detaching after fork from child process 18058] [Detaching after fork from child process 18061] [Detaching after fork from child process 18064] [Detaching after fork from child process 18067] [Detaching after fork from child process 18070] [Detaching after fork from child process 18073] [Detaching after fork from child process 18076] [Detaching after fork from child process 18079] [Detaching after fork from child process 18082] [Detaching after fork from child process 18085] [Detaching after fork from child process 18088] [Detaching after fork from child process 18091] [Detaching after fork from child process 18094] [Detaching after fork from child process 18097] [Detaching after fork from child process 18100] [Detaching after fork from child process 18103] [Detaching after fork from child process 18106] [Detaching after fork from child process 18109] [Detaching after fork from child process 18112] [Detaching after fork from child process 18115] [Detaching after fork from child process 18118] [Detaching after fork from child process 18121] [Detaching after fork from child process 18124] [Detaching after fork from child process 18127] [Detaching after fork from child process 18130] [Detaching after fork from child process 18133] [Detaching after fork from child process 18136] [Detaching after fork from child process 18139] [Detaching after fork from child process 18142] [Detaching after fork from child process 18145] [Detaching after fork from child process 18148] [Detaching after fork from child process 18151] [Detaching after fork from child process 18154] [Detaching after fork from child process 18157] [Detaching after fork from child process 18160] [Detaching after fork from child process 18163] [Detaching after fork from child process 18166] [Detaching after fork from child process 18169] [Detaching after fork from child process 18175] [Detaching after fork from child process 18178] [Detaching after fork from child process 18181] [Detaching after fork from child process 18184] [Detaching after fork from child process 18187] [Detaching after fork from child process 18190] [Detaching after fork from child process 18193] | after pass reduction: 0 | pass progress: 0, last destructive: 0 | progress is good, do not quickly decrease factor wasm-reduce: src/tools/wasm-reduce.cpp:1267: int main(int, const char**): Assertion `newSize > 4' failed. Program received signal SIGABRT, Aborted. 0x00007ffff6ec4e97 in raise () from /lib/x86_64-linux-gnu/libc.so.6 (gdb) bt #0 0x00007ffff6ec4e97 in raise () from /lib/x86_64-linux-gnu/libc.so.6 #1 0x00007ffff6ec6801 in abort () from /lib/x86_64-linux-gnu/libc.so.6 #2 0x00007ffff6eb639a in ?? () from /lib/x86_64-linux-gnu/libc.so.6 #3 0x00007ffff6eb6412 in __assert_fail () from /lib/x86_64-linux-gnu/libc.so.6 #4 0x000055555571ff2a in main () (gdb) ```
fitzgen commented 4 years ago

The failing assertion:

https://github.com/WebAssembly/binaryen/blob/7168130/src/tools/wasm-reduce.cpp#L1267

kripken commented 4 years ago

Hmm, binaryen and wabt don't seem to recognize the input wasm file as valid. I think --force is skipping over that error, and then it breaks down later.

Is this perhaps using multivalue or something else not yet supported in binaryen and wabt?

fitzgen commented 4 years ago

Correct. This is both using multi-value, and it is not a valid wasm file. That said, it is almost a valid wasm file, and I'd expect that wasm-reduce would be able to reduce such inputs. Is this not a supported use case?

fitzgen commented 4 years ago

(See also https://github.com/WebAssembly/wabt/issues/1331 for the disassembly)

kripken commented 4 years ago

Oh, no, sorry - wasm-reduce depends on the ability of binaryen to read the wasm and use its structure in order to reduce it. If it can't read it, it can't do anything. I updated the docs on https://github.com/WebAssembly/binaryen/wiki/Fuzzing now.

fitzgen commented 4 years ago

Ah okay, thanks for the explanation! Should we close this issue then, or did you want to keep it open for tracking work to exit gracefully (potentially with an error message) rather than abort?

kripken commented 4 years ago

I think the abort is only reached if -f is passed, so I don't think it's a high priority to fix, and I'm not sure offhand how to do it, so I suspect it's not worth it. I think maybe the docs I updated are good enough here. Closing. Thanks again for reporting!