arlyon opened issue #8033:
Thanks for filing a feature request! Please fill out the TODOs below.
Feature
I am using a WasiHttpView to selectively allow / reject destination authorities for the outgoing-handler. If the sandbox rejects a request, I would expect it to return an error to
outgoing_handler::handle
on the guest such that they may handle it, however that is not the case.fn send_request( &mut self, request: wasmtime_wasi_http::types::OutgoingRequest, ) -> wasmtime::Result< wasmtime::component::Resource<wasmtime_wasi_http::types::HostFutureIncomingResponse>, > where Self: Sized, { // try to remove the port if it exists let authority = request .authority .rsplit_once(':') .map(|(authority, _)| authority) .unwrap_or(&request.authority); if !self.allowed_authorities.contains(authority) { tracing::error!( "plugin tried to access {} which is not in the list of allowed authorities", authority ); return Err(wasmtime::Error::msg("not allowed to access authority")); } default_send_request(self, request) } // inside guest let Ok(result) = outgoing_handler::handle(req, None) else { tracing::error!("unable to send request"); continue; };
In reality, throwing an error here does not return control to the guest, but throws an error which is trapped by the runtime. Note the first line is my error handling:
Error: 0: plugin london failed to update: error while executing at wasm backtrace: 0: 0x4cf4f - wit-component:shim!indirect-wasi:http/outgoing-handler@0.2.0-handle 1: 0x33c42 - <unknown>!<wasm function 881> Caused by: not allowed to access authority Stack backtrace: 0: anyhow::error::<impl anyhow::Error>::msg at /home/arlyon/.cargo/registry/src/index.crates.io-6f17d22bba15001f/anyhow-1.0.77/src/error.rs:83:36 1: <litehouse::runtime::PluginRunner<T> as wasmtime_wasi_http::types::WasiHttpView>::send_request at ./crates/litehouse/src/runtime.rs:94:24 2: wasmtime_wasi_http::http_impl::<impl wasmtime_wasi_http::bindings::wasi::http::outgoing_handler::Host for T>::handle at /home/arlyon/.cargo/git/checkouts/wasmtime-41807828cb3a7a7e/4d54a99/crates/wasi-http/src/http_impl.rs:97:15 3: wasmtime_wasi_http::bindings::wasi::http::outgoing_handler::add_to_linker::{{closure}} at /home/arlyon/.cargo/git/checkouts/wasmtime-41807828cb3a7a7e/4d54a99/crates/wasi-http/src/lib.rs:11:5 4: wasmtime::runtime::component::func::host::HostFunc::entrypoint::{{closure}}::{{closure}} at /home/arlyon/.cargo/git/checkouts/wasmtime-41807828cb3a7a7e/4d54a99/crates/wasmtime/src/runtime/component/func/host.rs:68:35 5: wasmtime::runtime::component::func::host::call_host at /home/arlyon/.cargo/git/checkouts/wasmtime-41807828cb3a7a7e/4d54a99/crates/wasmtime/src/runtime/component/func/host.rs:227:15 6: wasmtime::runtime::component::func::host::HostFunc::entrypoint::{{closure}} at /home/arlyon/.cargo/git/checkouts/wasmtime-41807828cb3a7a7e/4d54a99/crates/wasmtime/src/runtime/component/func/host.rs:60:17 7: <core::panic::unwind_safe::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once at /rustc/30dfb9e046aeb878db04332c74de76e52fb7db10/library/core/src/panic/unwind_safe.rs:272:9
Benefit
Plugins should be allowed to recover in this case.
Implementation
No dice, I am not super familiar with how adding this capability would fit into the wider system.
Alternatives
For now, crashing the plugin is OK but not desirable. I would like the plugin author to be able to control how it is handled.
arlyon edited issue #8033:
Thanks for filing a feature request! Please fill out the TODOs below.
Feature
I am using a WasiHttpView to selectively allow / reject destination authorities for the outgoing-handler. If the sandbox rejects a request, I would expect it to return an error to
outgoing_handler::handle
on the guest such that they may handle it, however that is not the case.fn send_request( &mut self, request: wasmtime_wasi_http::types::OutgoingRequest, ) -> wasmtime::Result< wasmtime::component::Resource<wasmtime_wasi_http::types::HostFutureIncomingResponse>, > where Self: Sized, { // try to remove the port if it exists let authority = request .authority .rsplit_once(':') .map(|(authority, _)| authority) .unwrap_or(&request.authority); if !self.allowed_authorities.contains(authority) { tracing::error!( "plugin tried to access {} which is not in the list of allowed authorities", authority ); return Err(wasmtime::Error::msg("not allowed to access authority")); } default_send_request(self, request) } // inside guest let Ok(result) = outgoing_handler::handle(req, None) else { tracing::error!("unable to send request"); continue; };
In reality, throwing an error here does not return control to the guest, but throws an error which is trapped by the runtime. Note the first line is my error handling:
Error: 0: plugin london failed to update: error while executing at wasm backtrace: 0: 0x4cf4f - wit-component:shim!indirect-wasi:http/outgoing-handler@0.2.0-handle 1: 0x33c42 - <unknown>!<wasm function 881> Caused by: not allowed to access authority Stack backtrace: 0: anyhow::error::<impl anyhow::Error>::msg at /home/arlyon/.cargo/registry/src/index.crates.io-6f17d22bba15001f/anyhow-1.0.77/src/error.rs:83:36 1: <litehouse::runtime::PluginRunner<T> as wasmtime_wasi_http::types::WasiHttpView>::send_request at ./crates/litehouse/src/runtime.rs:94:24 2: wasmtime_wasi_http::http_impl::<impl wasmtime_wasi_http::bindings::wasi::http::outgoing_handler::Host for T>::handle at /home/arlyon/.cargo/git/checkouts/wasmtime-41807828cb3a7a7e/4d54a99/crates/wasi-http/src/http_impl.rs:97:15 3: wasmtime_wasi_http::bindings::wasi::http::outgoing_handler::add_to_linker::{{closure}} at /home/arlyon/.cargo/git/checkouts/wasmtime-41807828cb3a7a7e/4d54a99/crates/wasi-http/src/lib.rs:11:5 4: wasmtime::runtime::component::func::host::HostFunc::entrypoint::{{closure}}::{{closure}} at /home/arlyon/.cargo/git/checkouts/wasmtime-41807828cb3a7a7e/4d54a99/crates/wasmtime/src/runtime/component/func/host.rs:68:35 5: wasmtime::runtime::component::func::host::call_host at /home/arlyon/.cargo/git/checkouts/wasmtime-41807828cb3a7a7e/4d54a99/crates/wasmtime/src/runtime/component/func/host.rs:227:15 6: wasmtime::runtime::component::func::host::HostFunc::entrypoint::{{closure}} at /home/arlyon/.cargo/git/checkouts/wasmtime-41807828cb3a7a7e/4d54a99/crates/wasmtime/src/runtime/component/func/host.rs:60:17 7: <core::panic::unwind_safe::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once at /rustc/30dfb9e046aeb878db04332c74de76e52fb7db10/library/core/src/panic/unwind_safe.rs:272:9 ...
Benefit
Plugins should be allowed to recover in this case.
Implementation
No dice, I am not super familiar with how adding this capability would fit into the wider system.
Alternatives
For now, crashing the plugin is OK but not desirable. I would like the plugin author to be able to control how it is handled.
alexcrichton commented on issue #8033:
Thanks for the report!
In the WIT itself there's the ability to return an
error-code
, and would that be sufficient for your use case here? If so I think that theWasiHttpView
isn't quite set up to plumb an error through to the place where it's called, for example here the error is propagated with?
which is where the trap comes from. If that location is updated to try to downcast the error to anErrorCode
, however, that I think would then enable you to return anErrorCode
in your custom implementation?Would you be interested in making a PR for this change?
arlyon commented on issue #8033:
Yes! Thanks for the pointers, the change was fairly straightforward. Figuring out the test setup was a little more complex but all good now. PR linked above.
alexcrichton closed issue #8033:
Thanks for filing a feature request! Please fill out the TODOs below.
Feature
I am using a WasiHttpView to selectively allow / reject destination authorities for the outgoing-handler. If the sandbox rejects a request, I would expect it to return an error to
outgoing_handler::handle
on the guest such that they may handle it, however that is not the case.fn send_request( &mut self, request: wasmtime_wasi_http::types::OutgoingRequest, ) -> wasmtime::Result< wasmtime::component::Resource<wasmtime_wasi_http::types::HostFutureIncomingResponse>, > where Self: Sized, { // try to remove the port if it exists let authority = request .authority .rsplit_once(':') .map(|(authority, _)| authority) .unwrap_or(&request.authority); if !self.allowed_authorities.contains(authority) { tracing::error!( "plugin tried to access {} which is not in the list of allowed authorities", authority ); return Err(wasmtime::Error::msg("not allowed to access authority")); } default_send_request(self, request) } // inside guest let Ok(result) = outgoing_handler::handle(req, None) else { tracing::error!("unable to send request"); continue; };
In reality, throwing an error here does not return control to the guest, but throws an error which is trapped by the runtime. Note the first line is my error handling:
Error: 0: plugin london failed to update: error while executing at wasm backtrace: 0: 0x4cf4f - wit-component:shim!indirect-wasi:http/outgoing-handler@0.2.0-handle 1: 0x33c42 - <unknown>!<wasm function 881> Caused by: not allowed to access authority Stack backtrace: 0: anyhow::error::<impl anyhow::Error>::msg at /home/arlyon/.cargo/registry/src/index.crates.io-6f17d22bba15001f/anyhow-1.0.77/src/error.rs:83:36 1: <litehouse::runtime::PluginRunner<T> as wasmtime_wasi_http::types::WasiHttpView>::send_request at ./crates/litehouse/src/runtime.rs:94:24 2: wasmtime_wasi_http::http_impl::<impl wasmtime_wasi_http::bindings::wasi::http::outgoing_handler::Host for T>::handle at /home/arlyon/.cargo/git/checkouts/wasmtime-41807828cb3a7a7e/4d54a99/crates/wasi-http/src/http_impl.rs:97:15 3: wasmtime_wasi_http::bindings::wasi::http::outgoing_handler::add_to_linker::{{closure}} at /home/arlyon/.cargo/git/checkouts/wasmtime-41807828cb3a7a7e/4d54a99/crates/wasi-http/src/lib.rs:11:5 4: wasmtime::runtime::component::func::host::HostFunc::entrypoint::{{closure}}::{{closure}} at /home/arlyon/.cargo/git/checkouts/wasmtime-41807828cb3a7a7e/4d54a99/crates/wasmtime/src/runtime/component/func/host.rs:68:35 5: wasmtime::runtime::component::func::host::call_host at /home/arlyon/.cargo/git/checkouts/wasmtime-41807828cb3a7a7e/4d54a99/crates/wasmtime/src/runtime/component/func/host.rs:227:15 6: wasmtime::runtime::component::func::host::HostFunc::entrypoint::{{closure}} at /home/arlyon/.cargo/git/checkouts/wasmtime-41807828cb3a7a7e/4d54a99/crates/wasmtime/src/runtime/component/func/host.rs:60:17 7: <core::panic::unwind_safe::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once at /rustc/30dfb9e046aeb878db04332c74de76e52fb7db10/library/core/src/panic/unwind_safe.rs:272:9 ...
Benefit
Plugins should be allowed to recover in this case.
Implementation
No dice, I am not super familiar with how adding this capability would fit into the wider system.
Alternatives
For now, crashing the plugin is OK but not desirable. I would like the plugin author to be able to control how it is handled.
alexcrichton commented on issue #8033:
Fixed in https://github.com/bytecodealliance/wasmtime/pull/8035, so closing (thanks!)
Last updated: Dec 23 2024 at 12:05 UTC