proxy-wasm / proxy-wasm-cpp-host

WebAssembly for Proxies (C++ host implementation)
Apache License 2.0
84 stars 69 forks source link

Host crashes when VM fails stoi #352

Closed bhakta0007 closed 1 year ago

bhakta0007 commented 1 year ago

My Proxy WASM VM code is trying to do this:

int d = stoi(std::string("ABCD"));

This causes the following crash. I can prevent this from the client with a try/catch but am wondering why the VM is able to cause the host to crash.

(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007ffff7a68859 in __GI_abort () at abort.c:79
#2  0x0000555555600b7f in proxy_wasm_host::Context::error(std::basic_string_view<char, std::char_traits<char> >) ()
#3  0x0000555555629847 in proxy_wasm::exports::wasi_unstable_proc_exit(proxy_wasm::Word) ()
#4  0x0000555555653d33 in proxy_wasm::ConvertFunctionWordToUint32<void (proxy_wasm::Word), &proxy_wasm::exports::wasi_unstable_proc_exit>::convertFunctionWordToUint32(unsigned int) ()
#5  0x0000555555689b50 in void std::__invoke_impl<void, void (*&)(unsigned int), unsigned int&>(std::__invoke_other, void (*&)(unsigned int), unsigned int&) ()
#6  0x00005555556860d5 in std::__invoke_result<void (*&)(unsigned int), unsigned int&>::type std::__invoke<void (*&)(unsigned int), unsigned int&>(void (*&)(unsigned int), unsigned int&) ()
#7  0x0000555555668913 in decltype(auto) std::__apply_impl<void (*&)(unsigned int), std::tuple<unsigned int>&, 0ul>(void (*&)(unsigned int), std::tuple<unsigned int>&, std::integer_sequence<unsigned long, 0ul>) ()
#8  0x0000555555668956 in decltype(auto) std::apply<void (*&)(unsigned int), std::tuple<unsigned int>&>(void (*&)(unsigned int), std::tuple<unsigned int>&) ()
#9  0x000055555566865b in proxy_wasm::WasmEdge::WasmEdge::registerHostFunctionImpl<unsigned int>(std::basic_string_view<char, std::char_traits<char> >, std::basic_string_view<char, std::char_traits<char> >, void (*)(unsigned int))::{lambda(void*, WasmEdge_CallingFrameContext const*, WasmEdge_Value const*, WasmEdge_Value*)#1}::operator()(void*, WasmEdge_CallingFrameContext const*, WasmEdge_Value const*, WasmEdge_Value*) const ()
#10 0x000055555566899a in proxy_wasm::WasmEdge::WasmEdge::registerHostFunctionImpl<unsigned int>(std::basic_string_view<char, std::char_traits<char> >, std::basic_string_view<char, std::char_traits<char> >, void (*)(unsigned int))::{lambda(void*, WasmEdge_CallingFrameContext const*, WasmEdge_Value const*, WasmEdge_Value*)#1}::_FUN(void*, WasmEdge_CallingFrameContext const*, WasmEdge_Value const*, WasmEdge_Value*) ()
#11 0x0000555555697cf7 in (anonymous namespace)::CAPIHostFunc::run(WasmEdge::Runtime::CallingFrame const&, cxx20::span<WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::UnknownRef, WasmEdge::FuncRef, WasmEdge::ExternRef> const, 18446744073709551615ul>, cxx20::span<WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::UnknownRef, WasmEdge::FuncRef, WasmEdge::ExternRef>, 18446744073709551615ul>) ()
#12 0x00005555557aeb34 in WasmEdge::Executor::Executor::enterFunction(WasmEdge::Runtime::StackManager&, WasmEdge::Runtime::Instance::FunctionInstance const&, WasmEdge::AST::Instruction const*, bool) ()
#13 0x00005555557d8062 in WasmEdge::Executor::Executor::runCallOp(WasmEdge::Runtime::StackManager&, WasmEdge::AST::Instruction const&, WasmEdge::AST::Instruction const*&, bool) ()
#14 0x00005555557793a8 in WasmEdge::Executor::Executor::execute(WasmEdge::Runtime::StackManager&, WasmEdge::AST::Instruction const*, WasmEdge::AST::Instruction const*) ()
#15 0x000055555577a2f1 in WasmEdge::Executor::Executor::runFunction(WasmEdge::Runtime::StackManager&, WasmEdge::Runtime::Instance::FunctionInstance const&, cxx20::span<WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::UnknownRef, WasmEdge::FuncRef, WasmEdge::ExternRef> const, 18446744073709551615ul>) ()
#16 0x00005555556ea545 in WasmEdge::Executor::Executor::invoke(WasmEdge::Runtime::Instance::FunctionInstance const&, cxx20::span<WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::UnknownRef, WasmEdge::FuncRef, WasmEdge::ExternRef> const, 18446744073709551615ul>, cxx20::span<WasmEdge::ValType const, 18446744073709551615ul>) ()
#17 0x000055555569efed in WasmEdge_ExecutorInvoke ()
#18 0x0000555555683d78 in proxy_wasm::WasmEdge::WasmEdge::getModuleFunctionImpl<proxy_wasm::Word, proxy_wasm::Word, proxy_wasm::Word, proxy_wasm::Word>(std::basic_string_view<char, std::char_traits<char> >, std::function<proxy_wasm::Word (proxy_wasm::ContextBase*, proxy_wasm::Word, proxy_wasm::Word, proxy_wasm::Word)>*)::{lambda(proxy_wasm::ContextBase*, proxy_wasm::Word, proxy_wasm::Word, proxy_wasm::Word)#1}::operator()(proxy_wasm::ContextBase*, proxy_wasm::Word, proxy_wasm::Word, proxy_wasm::Word) const ()
#19 0x000055555568ec82 in std::_Function_handler<proxy_wasm::Word (proxy_wasm::ContextBase*, proxy_wasm::Word, proxy_wasm::Word, proxy_wasm::Word), proxy_wasm::WasmEdge::WasmEdge::getModuleFunctionImpl<proxy_wasm::Word, proxy_wasm::Word, proxy_wasm::Word, proxy_wasm::Word>(std::basic_string_view<char, std::char_traits<char> >, std::function<proxy_wasm::Word (proxy_wasm::ContextBase*, proxy_wasm::Word, proxy_wasm::Word, proxy_wasm::Word)>*)::{lambda(proxy_wasm::ContextBase*, proxy_wasm::Word, proxy_wasm::Word, proxy_wasm::Word)#1}>::_M_invoke(std::_Any_data const&, proxy_wasm::ContextBase*&&, proxy_wasm::Word&&, proxy_wasm::ContextBase*&&, proxy_wasm::ContextBase*&&) ()
#20 0x00005555556210d0 in std::function<proxy_wasm::Word (proxy_wasm::ContextBase*, proxy_wasm::Word, proxy_wasm::Word, proxy_wasm::Word)>::operator()(proxy_wasm::ContextBase*, proxy_wasm::Word, proxy_wasm::Word, proxy_wasm::Word) const ()
#21 0x000055555561cf94 in proxy_wasm::ContextBase::onRequestHeaders(unsigned int, bool) ()

update: I tried with WAMR runtime with similar outcome

(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007ffff7a68859 in __GI_abort () at abort.c:79
#2  0x00005555556045bf in proxy_wasm_host::Context::error(std::basic_string_view<char, std::char_traits<char> >) ()
#3  0x000055555562d5c9 in proxy_wasm::exports::wasi_unstable_proc_exit(proxy_wasm::Word) ()
#4  0x0000555555657ab5 in proxy_wasm::ConvertFunctionWordToUint32<void (proxy_wasm::Word), &proxy_wasm::exports::wasi_unstable_proc_exit>::convertFunctionWordToUint32(unsigned int) ()
#5  0x000055555568b686 in void std::__invoke_impl<void, void (*&)(unsigned int), unsigned int&>(std::__invoke_other, void (*&)(unsigned int), unsigned int&) ()
#6  0x0000555555688437 in std::__invoke_result<void (*&)(unsigned int), unsigned int&>::type std::__invoke<void (*&)(unsigned int), unsigned int&>(void (*&)(unsigned int), unsigned int&) ()
#7  0x000055555566c88f in decltype(auto) std::__apply_impl<void (*&)(unsigned int), std::tuple<unsigned int>&, 0ul>(void (*&)(unsigned int), std::tuple<unsigned int>&, std::integer_sequence<unsigned long, 0ul>) ()
#8  0x000055555566c8d2 in decltype(auto) std::apply<void (*&)(unsigned int), std::tuple<unsigned int>&>(void (*&)(unsigned int), std::tuple<unsigned int>&) ()
#9  0x000055555566c683 in proxy_wasm::wamr::Wamr::registerHostFunctionImpl<unsigned int>(std::basic_string_view<char, std::char_traits<char> >, std::basic_string_view<char, std::char_traits<char> >, void (*)(unsigned int))::{lambda(void*, wasm_val_vec_t const*, wasm_val_vec_t*)#1}::operator()(void*, wasm_val_vec_t const*, wasm_val_vec_t*) const ()
#10 0x000055555566c90b in proxy_wasm::wamr::Wamr::registerHostFunctionImpl<unsigned int>(std::basic_string_view<char, std::char_traits<char> >, std::basic_string_view<char, std::char_traits<char> >, void (*)(unsigned int))::{lambda(void*, wasm_val_vec_t const*, wasm_val_vec_t*)#1}::_FUN(void*, wasm_val_vec_t const*, wasm_val_vec_t*) ()
#11 0x00005555556a1d79 in wasm_runtime_invoke_c_api_native ()
#12 0x00005555556a81d3 in wasm_interp_call_func_native ()
#13 0x00005555556a8f66 in wasm_interp_call_func_bytecode ()
#14 0x00005555556ab8e7 in wasm_interp_call_wasm ()
#15 0x00005555556a2369 in call_wasm_with_hw_bound_check ()
#16 0x00005555556a2bde in wasm_call_function ()
#17 0x000055555569ca61 in wasm_func_call ()
#18 0x0000555555685cc4 in proxy_wasm::wamr::Wamr::getModuleFunctionImpl<proxy_wasm::Word, proxy_wasm::Word, proxy_wasm::Word, proxy_wasm::Word>(std::basic_string_view<char, std::char_traits<char> >, std::function<proxy_wasm::Word (proxy_wasm::ContextBase*, proxy_wasm::Word, proxy_wasm::Word, proxy_wasm::Word)>*)::{lambda(proxy_wasm::ContextBase*, proxy_wasm::Word, proxy_wasm::Word, proxy_wasm::Word)#1}::operator()(proxy_wasm::ContextBase*, proxy_wasm::Word, proxy_wasm::Word, proxy_wasm::Word) const ()
#19 0x000055555569053f in std::_Function_handler<proxy_wasm::Word (proxy_wasm::ContextBase*, proxy_wasm::Word, proxy_wasm::Word, proxy_wasm::Word), proxy_wasm::wamr::Wamr::getModuleFunctionImpl<proxy_wasm::Word, proxy_wasm::Word, proxy_wasm::Word, proxy_wasm::Word>(std::basic_string_view<char, std::char_traits<char> >, std::function<proxy_wasm::Word (proxy_wasm::ContextBase*, proxy_wasm::Word, proxy_wasm::Word, proxy_wasm::Word)>*)::{lambda(proxy_wasm::ContextBase*, proxy_wasm::Word, proxy_wasm::Word, proxy_wasm::Word)#1}>::_M_invoke(std::_Any_data const&, proxy_wasm::ContextBase*&&, proxy_wasm::Word&&, proxy_wasm::ContextBase*&&, proxy_wasm::ContextBase*&&) ()
#20 0x0000555555624e52 in std::function<proxy_wasm::Word (proxy_wasm::ContextBase*, proxy_wasm::Word, proxy_wasm::Word, proxy_wasm::Word)>::operator()(proxy_wasm::ContextBase*, proxy_wasm::Word, proxy_wasm::Word, proxy_wasm::Word) const ()
#21 0x0000555555620d16 in proxy_wasm::ContextBase::onRequestHeaders(unsigned int, bool) ()
PiotrSikora commented 1 year ago

Your host implementation crashes because the plugin is calling exit() (mapped to WASI's proc_exit()) that calls Context::error(), which in the default interface calls abort().

You need to override this and other methods in your host implementation. @mpwarres might have some pointers.