From 288e66a9c0fc6517015643d4c04c5e700b922d1b Mon Sep 17 00:00:00 2001 From: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com> Date: Thu, 28 Aug 2025 14:36:41 -0700 Subject: [PATCH 1/2] Only clear io buffer after unsuccesfull guest call. Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com> Undo stuff that breaks unwinding Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com> --- .../src/sandbox/initialized_multi_use.rs | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/hyperlight_host/src/sandbox/initialized_multi_use.rs b/src/hyperlight_host/src/sandbox/initialized_multi_use.rs index 82a920158..cf1d1ac16 100644 --- a/src/hyperlight_host/src/sandbox/initialized_multi_use.rs +++ b/src/hyperlight_host/src/sandbox/initialized_multi_use.rs @@ -425,9 +425,14 @@ impl MultiUseSandbox { .get_guest_function_call_result() })(); - // TODO: Do we want to allow re-entrant guest function calls? - self.get_mgr_wrapper_mut().as_mut().clear_io_buffers(); - + // In the happy path we do not need to clear io-buffers from the host because: + // - the serialized guest function call is zeroed out by the guest during deserialization, see call to `try_pop_shared_input_data_into::()` + // - the serialized guest function result is zeroed out by us (the host) during deserialization, see `get_guest_function_call_result` + // - any serialized host function call are zeroed out by us (the host) during deserialization, see `get_host_function_call` + // - any serialized host function result is zeroed out by the guest during deserialization, see `get_host_return_value` + if res.is_err() { + self.get_mgr_wrapper_mut().as_mut().clear_io_buffers(); + } res } @@ -506,6 +511,25 @@ mod tests { use crate::sandbox::SandboxConfiguration; use crate::{GuestBinary, HyperlightError, MultiUseSandbox, Result, UninitializedSandbox}; + /// Make sure input/output buffers are properly reset after guest call (with host call) + #[test] + fn io_buffer_reset() { + let mut cfg = SandboxConfiguration::default(); + cfg.set_input_data_size(4096); + cfg.set_output_data_size(4096); + let path = simple_guest_as_string().unwrap(); + let mut sandbox = + UninitializedSandbox::new(GuestBinary::FilePath(path), Some(cfg)).unwrap(); + sandbox.register("HostAdd", |a: i32, b: i32| a + b).unwrap(); + let mut sandbox = sandbox.evolve().unwrap(); + + // will exhaust io if leaky + for _ in 0..1000 { + let result = sandbox.call::("Add", (5i32, 10i32)).unwrap(); + assert_eq!(result, 15); + } + } + /// Tests that call_guest_function_by_name restores the state correctly #[test] fn test_call_guest_function_by_name() { From 1d7ff9a9dfd1d8a38ed82346315bc0f51164746e Mon Sep 17 00:00:00 2001 From: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com> Date: Mon, 8 Sep 2025 10:36:38 -0700 Subject: [PATCH 2/2] Add error path to test Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com> --- src/hyperlight_host/src/sandbox/initialized_multi_use.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/hyperlight_host/src/sandbox/initialized_multi_use.rs b/src/hyperlight_host/src/sandbox/initialized_multi_use.rs index cf1d1ac16..dfdcc9668 100644 --- a/src/hyperlight_host/src/sandbox/initialized_multi_use.rs +++ b/src/hyperlight_host/src/sandbox/initialized_multi_use.rs @@ -502,6 +502,7 @@ mod tests { use std::sync::{Arc, Barrier}; use std::thread; + use hyperlight_common::flatbuffer_wrappers::guest_error::ErrorCode; use hyperlight_testing::simple_guest_as_string; #[cfg(target_os = "linux")] @@ -523,10 +524,14 @@ mod tests { sandbox.register("HostAdd", |a: i32, b: i32| a + b).unwrap(); let mut sandbox = sandbox.evolve().unwrap(); - // will exhaust io if leaky + // will exhaust io if leaky. Tests both success and error paths for _ in 0..1000 { let result = sandbox.call::("Add", (5i32, 10i32)).unwrap(); assert_eq!(result, 15); + let result = sandbox.call::("AddToStaticAndFail", ()).unwrap_err(); + assert!( + matches!(result, HyperlightError::GuestError (code, msg ) if code == ErrorCode::GuestError && msg == "Crash on purpose") + ); } }