From 46670b16bcbbdbe268999f53fb3894984ef43982 Mon Sep 17 00:00:00 2001 From: Simon Davies Date: Tue, 13 May 2025 21:52:07 +0100 Subject: [PATCH] Remove in process mode from hyperlight-host Signed-off-by: Simon Davies --- .github/workflows/dep_rust.yml | 4 +- Justfile | 4 +- docs/debugging-hyperlight.md | 48 ------ src/hyperlight_host/Cargo.toml | 1 - src/hyperlight_host/build.rs | 3 - .../src/func/guest_dispatch.rs | 14 -- .../src/hypervisor/hypervisor_handler.rs | 155 +++++++----------- src/hyperlight_host/src/hypervisor/mod.rs | 3 - src/hyperlight_host/src/mem/custom_drop.rs | 109 ------------ src/hyperlight_host/src/mem/layout.rs | 25 +-- src/hyperlight_host/src/mem/mgr.rs | 151 +++-------------- src/hyperlight_host/src/mem/mod.rs | 3 - src/hyperlight_host/src/mem/shared_mem.rs | 11 +- .../src/sandbox/leaked_outb.rs | 129 --------------- src/hyperlight_host/src/sandbox/mem_mgr.rs | 9 +- src/hyperlight_host/src/sandbox/mod.rs | 6 - src/hyperlight_host/src/sandbox/outb.rs | 32 +--- .../src/sandbox/uninitialized.rs | 55 +------ .../src/sandbox_state/sandbox.rs | 6 - src/hyperlight_host/tests/common/mod.rs | 20 --- src/hyperlight_host/tests/integration_test.rs | 26 +-- .../tests/sandbox_host_tests.rs | 13 +- 22 files changed, 110 insertions(+), 717 deletions(-) delete mode 100644 docs/debugging-hyperlight.md delete mode 100644 src/hyperlight_host/src/mem/custom_drop.rs delete mode 100644 src/hyperlight_host/src/sandbox/leaked_outb.rs diff --git a/.github/workflows/dep_rust.yml b/.github/workflows/dep_rust.yml index ebcaa3636..8721f445e 100644 --- a/.github/workflows/dep_rust.yml +++ b/.github/workflows/dep_rust.yml @@ -102,8 +102,8 @@ jobs: # with default features just test ${{ matrix.config }} ${{ matrix.hypervisor == 'mshv3' && 'mshv3' || ''}} - # with only one driver enabled (driver mshv/kvm feature is ignored on windows) + seccomp + inprocess - just test ${{ matrix.config }} inprocess,seccomp,${{ matrix.hypervisor == 'mshv' && 'mshv2' || matrix.hypervisor == 'mshv3' && 'mshv3' || 'kvm' }} + # with only one driver enabled (driver mshv/kvm feature is ignored on windows) + seccomp + just test ${{ matrix.config }} seccomp,${{ matrix.hypervisor == 'mshv' && 'mshv2' || matrix.hypervisor == 'mshv3' && 'mshv3' || 'kvm' }} # make sure certain cargo features compile cargo check -p hyperlight-host --features crashdump diff --git a/Justfile b/Justfile index dd83d425b..8440b36b5 100644 --- a/Justfile +++ b/Justfile @@ -61,8 +61,8 @@ test-like-ci config=default-target hypervisor="kvm": @# with default features just test {{config}} {{ if hypervisor == "mshv3" {"mshv3"} else {""} }} - @# with only one driver enabled + seccomp + inprocess - just test {{config}} inprocess,seccomp,{{ if hypervisor == "mshv" {"mshv2"} else if hypervisor == "mshv3" {"mshv3"} else {"kvm"} }} + @# with only one driver enabled + seccomp + just test {{config}} seccomp,{{ if hypervisor == "mshv" {"mshv2"} else if hypervisor == "mshv3" {"mshv3"} else {"kvm"} }} @# make sure certain cargo features compile cargo check -p hyperlight-host --features crashdump diff --git a/docs/debugging-hyperlight.md b/docs/debugging-hyperlight.md deleted file mode 100644 index 8abb9a645..000000000 --- a/docs/debugging-hyperlight.md +++ /dev/null @@ -1,48 +0,0 @@ -# Debugging Hyperlight - -Support for debugging Hyperlight is currently very limited and experimental. Despite this we offer some very primitive tools to help. - -When creating a Uninitialized sandbox, passing a `SandboxRunOptions::RunInProcess(false)` will make the guest run inside a regular host process, rather than inside a hypervisor partition. This allows you to step through the code of the guest using your IDE's debugger. However, there are no symbols, and breakpoints are not supported, so you'll be stepping through assembly. - -However, on Windows platform, passing `SandboxRunOptions::RunInProcess(true)` is supported, and will load the guest binary using the win32 `LoadLibrary` function. This has the advantage of also allowing your IDE to set breakpoints in the guest, and also loading symbols, allowing for easy debugging. - -## Notes on running guest in-process - -The support for running a guest using in-process mode is experimental, highly unsafe, and has many limitations. It requires -enabling cargo feature `inprocess`, and only works when hyperlight-host is built with debug_assertions. Inprocess currently does not support calling guest functions that returns errors. If a guest panics, it will surface as assertion fault ""ERROR: The guest either panicked or returned an Error. Running inprocess-mode currently does not support error handling." - -Running in process is specifically only for testing, and should never be used in production as it offers no security guarantees. - -## Logging - -Hyperlight guests supports logging using the log crate. Any log records logged inside a hyperlight guest using the various -log macros trace!/info!/warning!, etc., will be logged, given that a logger has been instantiated in the host. This can be -very helpful for debugging as well. - -## Getting debug print output of memory configuration, virtual processor register state, and other information - -Enabling the feature `print_debug` and running a debug build will result in some debug output being printed to the console. Amongst other things this output will show the memory configuration and virtual processor register state. - -To enable this permanently in the rust analyzer for Visual Studio Code so that this output shows when running tests using `Run Test` option add the following to your `settings.json` file: - -```json -"rust-analyzer.runnables.extraArgs": [ - "--features=print_debug" -], -``` - -Alternatively, this can be enabled when running a test from the command line: - -```sh -cargo test --package hyperlight-host --test integration_test --features print_debug -- static_stack_allocate --exact --show-output -``` - -## Dumping the memory configuration, virtual processor register state and memory contents on a crash or unexpected VM Exit - -To dump the details of the memory configuration, the virtual processors register state and the contents of the VM memory set the feature `crashdump` and run a debug build. This will result in a dump file being created in the temporary directory. The name and location of the dump file will be printed to the console and logged as an error message. - -There are no tools at this time to analyze the dump file, but it can be useful for debugging. - -## Debugging guests - -For more information on how to debug the Hyperlight guests check the following [link](./how-to-debug-a-hyperlight-guest.md). diff --git a/src/hyperlight_host/Cargo.toml b/src/hyperlight_host/Cargo.toml index 2fc326015..e91a4f834 100644 --- a/src/hyperlight_host/Cargo.toml +++ b/src/hyperlight_host/Cargo.toml @@ -126,7 +126,6 @@ crashdump = ["dep:tempfile"] # Dumps the VM state to a file on unexpected errors kvm = ["dep:kvm-bindings", "dep:kvm-ioctls"] mshv2 = ["dep:mshv-bindings2", "dep:mshv-ioctls2"] mshv3 = ["dep:mshv-bindings3", "dep:mshv-ioctls3"] -inprocess = [] # This enables easy debug in the guest gdb = ["dep:gdbstub", "dep:gdbstub_arch"] fuzzing = ["hyperlight-common/fuzzing"] diff --git a/src/hyperlight_host/build.rs b/src/hyperlight_host/build.rs index e82f75d9a..7818c1257 100644 --- a/src/hyperlight_host/build.rs +++ b/src/hyperlight_host/build.rs @@ -92,9 +92,6 @@ fn main() -> Result<()> { gdb: { all(feature = "gdb", debug_assertions, any(feature = "kvm", feature = "mshv2", feature = "mshv3"), target_os = "linux") }, kvm: { all(feature = "kvm", target_os = "linux") }, mshv: { all(any(feature = "mshv2", feature = "mshv3"), target_os = "linux") }, - // inprocess feature is aliased with debug_assertions to make it only available in debug-builds. - // You should never use #[cfg(feature = "inprocess")] in the codebase. Use #[cfg(inprocess)] instead. - inprocess: { all(feature = "inprocess", debug_assertions) }, // crashdump feature is aliased with debug_assertions to make it only available in debug-builds. crashdump: { all(feature = "crashdump", debug_assertions) }, // print_debug feature is aliased with debug_assertions to make it only available in debug-builds. diff --git a/src/hyperlight_host/src/func/guest_dispatch.rs b/src/hyperlight_host/src/func/guest_dispatch.rs index 02cf7b7d1..9d4cb0c55 100644 --- a/src/hyperlight_host/src/func/guest_dispatch.rs +++ b/src/hyperlight_host/src/func/guest_dispatch.rs @@ -349,19 +349,6 @@ mod tests { call_guest_function_by_name_hv(); } - #[test] - #[cfg(inprocess)] - fn test_call_guest_function_by_name_in_proc_manual() { - let u_sbox = UninitializedSandbox::new( - guest_bin(), - None, - Some(crate::SandboxRunOptions::RunInProcess(false)), - None, - ) - .unwrap(); - test_call_guest_function_by_name(u_sbox); - } - fn terminate_vcpu_after_1000ms() -> Result<()> { // This test relies upon a Hypervisor being present so for now // we will skip it if there isn't one. @@ -456,7 +443,6 @@ mod tests { } #[test] - #[cfg(not(inprocess))] fn test_trigger_exception_on_guest() { let usbox = UninitializedSandbox::new( GuestBinary::FilePath(simple_guest_as_string().expect("Guest Binary Missing")), diff --git a/src/hyperlight_host/src/hypervisor/hypervisor_handler.rs b/src/hyperlight_host/src/hypervisor/hypervisor_handler.rs index 591f43a07..450668130 100644 --- a/src/hyperlight_host/src/hypervisor/hypervisor_handler.rs +++ b/src/hyperlight_host/src/hypervisor/hypervisor_handler.rs @@ -240,8 +240,6 @@ impl HypervisorHandler { #[cfg(gdb)] debug_info: Option, ) -> Result<()> { let configuration = self.configuration.clone(); - #[cfg(target_os = "windows")] - let in_process = sandbox_memory_manager.is_in_process(); *self .execution_variables @@ -309,11 +307,7 @@ impl HypervisorHandler { let hv = hv.as_mut().ok_or_else(|| new_error!("Hypervisor not set"))?; #[cfg(target_os = "windows")] - if !in_process { - execution_variables - .set_partition_handle(hv.get_partition_handle())?; - } - + execution_variables.set_partition_handle(hv.get_partition_handle())?; #[cfg(target_os = "linux")] { // We cannot use the Killable trait, so we get the `pthread_t` via a libc @@ -867,100 +861,73 @@ fn set_up_hypervisor_partition( pml4_ptr ); } - if mgr.is_in_process() { - cfg_if::cfg_if! { - if #[cfg(inprocess)] { - // in-process feature + debug build - use super::inprocess::InprocessArgs; - use crate::sandbox::leaked_outb::LeakedOutBWrapper; - use super::inprocess::InprocessDriver; - - let leaked_outb_wrapper = LeakedOutBWrapper::new(mgr, outb_handler)?; - let hv = InprocessDriver::new(InprocessArgs { - entrypoint_raw: u64::from(mgr.load_addr.clone() + mgr.entrypoint_offset), - peb_ptr_raw: mgr - .get_in_process_peb_address(mgr.shared_mem.base_addr() as u64)?, - leaked_outb_wrapper, - })?; - Ok(Box::new(hv)) - } else if #[cfg(inprocess)]{ - // in-process feature, but not debug build - log_then_return!("In-process mode is only available on debug-builds"); - } else if #[cfg(debug_assertions)] { - // debug build without in-process feature - log_then_return!("In-process mode requires `inprocess` cargo feature"); - } else { - log_then_return!("In-process mode requires `inprocess` cargo feature and is only available on debug-builds"); - } - } - } else { - // Create gdb thread if gdb is enabled and the configuration is provided - // This is only done when the hypervisor is not in-process - #[cfg(gdb)] - let gdb_conn = if let Some(DebugInfo { port }) = debug_info { - let gdb_conn = create_gdb_thread(*port, unsafe { pthread_self() }); - // in case the gdb thread creation fails, we still want to continue - // without gdb - match gdb_conn { - Ok(gdb_conn) => Some(gdb_conn), - Err(e) => { - log::error!("Could not create gdb connection: {:#}", e); + // Create gdb thread if gdb is enabled and the configuration is provided + // This is only done when the hypervisor is not in-process + #[cfg(gdb)] + let gdb_conn = if let Some(DebugInfo { port }) = debug_info { + let gdb_conn = create_gdb_thread(*port, unsafe { pthread_self() }); - None - } - } - } else { - None - }; + // in case the gdb thread creation fails, we still want to continue + // without gdb + match gdb_conn { + Ok(gdb_conn) => Some(gdb_conn), + Err(e) => { + log::error!("Could not create gdb connection: {:#}", e); - match *get_available_hypervisor() { - #[cfg(mshv)] - Some(HypervisorType::Mshv) => { - let hv = crate::hypervisor::hyperv_linux::HypervLinuxDriver::new( - regions, - entrypoint_ptr, - rsp_ptr, - pml4_ptr, - #[cfg(gdb)] - gdb_conn, - )?; - Ok(Box::new(hv)) + None } + } + } else { + None + }; - #[cfg(kvm)] - Some(HypervisorType::Kvm) => { - let hv = crate::hypervisor::kvm::KVMDriver::new( - regions, - pml4_ptr.absolute()?, - entrypoint_ptr.absolute()?, - rsp_ptr.absolute()?, - #[cfg(gdb)] - gdb_conn, - )?; - Ok(Box::new(hv)) - } + match *get_available_hypervisor() { + #[cfg(mshv)] + Some(HypervisorType::Mshv) => { + let hv = crate::hypervisor::hyperv_linux::HypervLinuxDriver::new( + regions, + entrypoint_ptr, + rsp_ptr, + pml4_ptr, + #[cfg(gdb)] + gdb_conn, + )?; + Ok(Box::new(hv)) + } - #[cfg(target_os = "windows")] - Some(HypervisorType::Whp) => { - let mmap_file_handle = mgr - .shared_mem - .with_exclusivity(|e| e.get_mmap_file_handle())?; - let hv = crate::hypervisor::hyperv_windows::HypervWindowsDriver::new( - regions, - mgr.shared_mem.raw_mem_size(), // we use raw_* here because windows driver requires 64K aligned addresses, - mgr.shared_mem.raw_ptr() as *mut c_void, // and instead convert it to base_addr where needed in the driver itself - pml4_ptr.absolute()?, - entrypoint_ptr.absolute()?, - rsp_ptr.absolute()?, - HandleWrapper::from(mmap_file_handle), - )?; - Ok(Box::new(hv)) - } + #[cfg(kvm)] + Some(HypervisorType::Kvm) => { + let hv = crate::hypervisor::kvm::KVMDriver::new( + regions, + pml4_ptr.absolute()?, + entrypoint_ptr.absolute()?, + rsp_ptr.absolute()?, + #[cfg(gdb)] + gdb_conn, + )?; + Ok(Box::new(hv)) + } - _ => { - log_then_return!(NoHypervisorFound()); - } + #[cfg(target_os = "windows")] + Some(HypervisorType::Whp) => { + let mmap_file_handle = mgr + .shared_mem + .with_exclusivity(|e| e.get_mmap_file_handle())?; + let hv = crate::hypervisor::hyperv_windows::HypervWindowsDriver::new( + regions, + mgr.shared_mem.raw_mem_size(), // we use raw_* here because windows driver requires 64K aligned addresses, + mgr.shared_mem.raw_ptr() as *mut c_void, // and instead convert it to base_addr where needed in the driver itself + pml4_ptr.absolute()?, + entrypoint_ptr.absolute()?, + rsp_ptr.absolute()?, + HandleWrapper::from(mmap_file_handle), + )?; + Ok(Box::new(hv)) + } + + _ => { + log_then_return!(NoHypervisorFound()); } } } diff --git a/src/hyperlight_host/src/hypervisor/mod.rs b/src/hyperlight_host/src/hypervisor/mod.rs index bf85d3956..11ded324f 100644 --- a/src/hyperlight_host/src/hypervisor/mod.rs +++ b/src/hyperlight_host/src/hypervisor/mod.rs @@ -39,9 +39,6 @@ pub(crate) mod hypervisor_handler; #[cfg(gdb)] mod gdb; -/// Driver for running in process instead of using hypervisor -#[cfg(inprocess)] -pub mod inprocess; #[cfg(kvm)] /// Functionality to manipulate KVM-based virtual machines pub mod kvm; diff --git a/src/hyperlight_host/src/mem/custom_drop.rs b/src/hyperlight_host/src/mem/custom_drop.rs deleted file mode 100644 index 822632af0..000000000 --- a/src/hyperlight_host/src/mem/custom_drop.rs +++ /dev/null @@ -1,109 +0,0 @@ -/* -Copyright 2024 The Hyperlight Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -use std::fmt::Debug; - -use tracing::{instrument, Span}; - -/// A struct that stores a `*mut EltT` and allows the creator of the struct -/// to specify the functionality to be run when the struct is dropped. -/// -/// This struct is `Send`, but purposely not `Sync` or `Clone`, so you can -/// move these across threads but not duplicate them. Since you can't duplicate -/// them, you don't need to synchronize them across threads (i.e. `lock()`). -/// -/// If you do want to duplicate `CustomPtrDrop` instances, and synchronize -/// access to them across threads, put them inside of an -/// `Arc>`. That configuration is likely the most useful -pub(crate) struct CustomPtrDrop<'a, EltT> { - t: SendablePtr, - drop: Box, -} - -impl<'a, EltT> CustomPtrDrop<'a, EltT> { - #[instrument(skip_all, parent = Span::current(), level= "Trace")] - pub(crate) fn new(elt: *mut EltT, drop_fn: Box) -> Self { - Self { - t: SendablePtr(elt), - drop: drop_fn, - } - } - #[instrument(skip_all, parent = Span::current(), level= "Trace")] - pub(crate) fn as_mut_ptr(&self) -> *mut EltT { - self.t.0 - } -} - -impl<'a, EltT> Debug for CustomPtrDrop<'a, EltT> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("CustomDrop").finish() - } -} - -impl<'a, EltT> Drop for CustomPtrDrop<'a, EltT> { - #[instrument(skip_all, parent = Span::current(), level= "Trace")] - fn drop(&mut self) { - let drop_fn = &self.drop; - drop_fn(self.t.0) - } -} -struct SendablePtr(*mut T); - -unsafe impl Send for SendablePtr {} - -#[cfg(test)] -mod tests { - #[cfg(target_os = "windows")] - use std::sync::{Arc, Mutex}; - #[cfg(target_os = "windows")] - use std::thread; - - #[cfg(target_os = "windows")] - use super::CustomPtrDrop; - - /// A test to ensure that CustomDrop cannot be cloned, must be stored - /// inside an `Arc` to be able to be sent across threads, and must - /// be stored inside a `Mutex` to be sync-ed across threads. - /// - /// Further, ensures that the `drop` function is called when the - /// `CustomDrop` is dropped. - #[test] - #[cfg(target_os = "windows")] - fn test_custom_drop_multithreaded() { - let i_ptr = Box::into_raw(Box::new(1)); - let cd_arc = { - let cd = CustomPtrDrop::new( - i_ptr, - Box::new(|ptr| { - unsafe { - let _ = Box::from_raw(ptr); - }; - }), - ); - Arc::new(Mutex::new(cd)) - }; - - let mut join_handles = Vec::new(); - for _ in 0..10 { - let cd = cd_arc.clone(); - let join_handle = thread::spawn(move || print!("cd: {cd:?}")); - join_handles.push(join_handle); - } - for join_handle in join_handles { - join_handle.join().unwrap(); - } - } -} diff --git a/src/hyperlight_host/src/mem/layout.rs b/src/hyperlight_host/src/mem/layout.rs index 52949a255..ff5a0c26f 100644 --- a/src/hyperlight_host/src/mem/layout.rs +++ b/src/hyperlight_host/src/mem/layout.rs @@ -28,7 +28,7 @@ use super::mgr::AMOUNT_OF_MEMORY_PER_PT; use super::shared_mem::{ExclusiveSharedMemory, GuestSharedMemory, SharedMemory}; use crate::error::HyperlightError::{GuestOffsetIsInvalid, MemoryRequestTooBig}; use crate::sandbox::SandboxConfiguration; -use crate::{log_then_return, new_error, Result}; +use crate::{new_error, Result}; // +-------------------------------------------+ // | Guest (User) Stack | @@ -660,17 +660,10 @@ impl SandboxMemoryLayout { shared_mem: &mut ExclusiveSharedMemory, guest_offset: usize, size: usize, - run_inprocess: bool, ) -> Result<()> { macro_rules! get_address { ($something:ident) => { - if run_inprocess { - let offset = self.$something; - let calculated_addr = shared_mem.calculate_address(offset)?; - u64::try_from(calculated_addr)? - } else { - u64::try_from(guest_offset + self.$something)? - } + u64::try_from(guest_offset + self.$something)? }; } @@ -693,19 +686,7 @@ impl SandboxMemoryLayout { // skip outb and outb context, is set when running in_proc // Set RunMode in PEB - shared_mem.write_u64( - self.get_run_mode_offset(), - match ( - run_inprocess, - cfg!(target_os = "windows"), - cfg!(target_os = "linux"), - ) { - (false, _, _) => RunMode::Hypervisor as u64, - (true, true, _) => RunMode::InProcessWindows as u64, - (true, _, true) => RunMode::InProcessLinux as u64, - (true, _, _) => log_then_return!("Unsupported OS for in-process mode"), - }, - )?; + shared_mem.write_u64(self.get_run_mode_offset(), RunMode::Hypervisor as u64)?; // Set up input buffer pointer shared_mem.write_u64( diff --git a/src/hyperlight_host/src/mem/mgr.rs b/src/hyperlight_host/src/mem/mgr.rs index 4d8b8b2e1..ddb760280 100644 --- a/src/hyperlight_host/src/mem/mgr.rs +++ b/src/hyperlight_host/src/mem/mgr.rs @@ -62,8 +62,6 @@ pub(crate) struct SandboxMemoryManager { pub(crate) shared_mem: S, /// The memory layout of the underlying shared memory pub(crate) layout: SandboxMemoryLayout, - /// Whether the sandbox is running in-process - inprocess: bool, /// Pointer to where to load memory from pub(crate) load_addr: RawPtr, /// Offset for the execution entrypoint from `load_addr` @@ -82,25 +80,18 @@ where fn new( layout: SandboxMemoryLayout, shared_mem: S, - inprocess: bool, load_addr: RawPtr, entrypoint_offset: Offset, ) -> Self { Self { layout, shared_mem, - inprocess, load_addr, entrypoint_offset, snapshots: Arc::new(Mutex::new(Vec::new())), } } - #[instrument(skip_all, parent = Span::current(), level= "Trace")] - pub(crate) fn is_in_process(&self) -> bool { - self.inprocess - } - /// Get `SharedMemory` in `self` as a mutable reference pub(crate) fn get_shared_mem_mut(&mut self) -> &mut S { &mut self.shared_mem @@ -226,19 +217,6 @@ where } } - /// Get the process environment block (PEB) address assuming `start_addr` - /// is the address of the start of memory, using the given - /// `SandboxMemoryLayout` to calculate the address. - /// - /// For more details on PEBs, please see the following link: - /// - /// https://en.wikipedia.org/wiki/Process_Environment_Block - #[cfg(inprocess)] - #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")] - pub(crate) fn get_in_process_peb_address(&self, start_addr: u64) -> Result { - Ok(start_addr + self.layout.get_in_process_peb_offset() as u64) - } - /// this function will create a memory snapshot and push it onto the stack of snapshots /// It should be used when you want to save the state of the memory, for example, when evolving a sandbox to a new state pub(crate) fn push_state(&mut self) -> Result<()> { @@ -298,43 +276,6 @@ where } } -/// Common setup functionality for the -/// `load_guest_binary_{into_memory, using_load_library}` functions -/// -/// Returns the newly created `SandboxMemoryLayout`, newly created -/// `SharedMemory`, load address as calculated by `load_addr_fn`, -/// and calculated entrypoint offset, in order. -#[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")] -fn load_guest_binary_common( - cfg: SandboxConfiguration, - exe_info: &ExeInfo, - load_addr_fn: F, -) -> Result<(SandboxMemoryLayout, ExclusiveSharedMemory, RawPtr, Offset)> -where - F: FnOnce(&ExclusiveSharedMemory, &SandboxMemoryLayout) -> Result, -{ - let layout = SandboxMemoryLayout::new( - cfg, - exe_info.loaded_size(), - usize::try_from(cfg.get_stack_size(exe_info))?, - usize::try_from(cfg.get_heap_size(exe_info))?, - )?; - let mut shared_mem = ExclusiveSharedMemory::new(layout.get_memory_size()?)?; - - let load_addr: RawPtr = load_addr_fn(&shared_mem, &layout)?; - - let entrypoint_offset = exe_info.entrypoint(); - - let offset = layout.get_code_pointer_offset(); - - { - // write the code pointer to shared memory - let load_addr_u64: u64 = load_addr.clone().into(); - shared_mem.write_u64(offset, load_addr_u64)?; - } - Ok((layout, shared_mem, load_addr, entrypoint_offset)) -} - impl SandboxMemoryManager { /// Load the binary represented by `pe_info` into memory, ensuring /// all necessary relocations are made prior to completing the load @@ -346,53 +287,38 @@ impl SandboxMemoryManager { /// /// - The newly-created `SharedMemory` /// - The `SandboxMemoryLayout` describing that `SharedMemory` - /// - The offset to the entrypoint. This value means something different - /// depending on whether we're using in-process mode or not: - /// - If we're using in-process mode, this value will be into - /// host memory - /// - If we're not running with in-memory mode, this value will be - /// into guest memory + /// - The offset to the entrypoint. #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")] pub(crate) fn load_guest_binary_into_memory( cfg: SandboxConfiguration, exe_info: &mut ExeInfo, - inprocess: bool, ) -> Result { - let (layout, mut shared_mem, load_addr, entrypoint_offset) = load_guest_binary_common( + let layout = SandboxMemoryLayout::new( cfg, - exe_info, - |shared_mem: &ExclusiveSharedMemory, layout: &SandboxMemoryLayout| { - let addr_usize = if inprocess { - // if we're running in-process, load_addr is the absolute - // address to the start of shared memory, plus the offset to - // code - - // We also need to make the memory executable - - shared_mem.make_memory_executable()?; - shared_mem.base_addr() + layout.get_guest_code_offset() - } else { - // otherwise, we're running in a VM, so load_addr - // is the base address in a VM plus the code - // offset - layout.get_guest_code_address() - }; - RawPtr::try_from(addr_usize) - }, + exe_info.loaded_size(), + usize::try_from(cfg.get_stack_size(exe_info))?, + usize::try_from(cfg.get_heap_size(exe_info))?, )?; + let mut shared_mem = ExclusiveSharedMemory::new(layout.get_memory_size()?)?; + + let load_addr: RawPtr = RawPtr::try_from(layout.get_guest_code_address())?; + + let entrypoint_offset = exe_info.entrypoint(); + + let offset = layout.get_code_pointer_offset(); + + { + // write the code pointer to shared memory + let load_addr_u64: u64 = load_addr.clone().into(); + shared_mem.write_u64(offset, load_addr_u64)?; + } exe_info.load( load_addr.clone().try_into()?, &mut shared_mem.as_mut_slice()[layout.get_guest_code_offset()..], )?; - Ok(Self::new( - layout, - shared_mem, - inprocess, - load_addr, - entrypoint_offset, - )) + Ok(Self::new(layout, shared_mem, load_addr, entrypoint_offset)) } /// Set the stack guard to `cookie` using `layout` to calculate @@ -415,7 +341,6 @@ impl SandboxMemoryManager { SandboxMemoryManager { shared_mem: hshm, layout: self.layout, - inprocess: self.inprocess, load_addr: self.load_addr.clone(), entrypoint_offset: self.entrypoint_offset, snapshots: Arc::new(Mutex::new(Vec::new())), @@ -423,7 +348,6 @@ impl SandboxMemoryManager { SandboxMemoryManager { shared_mem: gshm, layout: self.layout, - inprocess: self.inprocess, load_addr: self.load_addr.clone(), entrypoint_offset: self.entrypoint_offset, snapshots: Arc::new(Mutex::new(Vec::new())), @@ -541,40 +465,3 @@ impl SandboxMemoryManager { ) } } - -#[cfg(test)] -mod tests { - use hyperlight_testing::rust_guest_as_pathbuf; - - use crate::mem::exe::ExeInfo; - use crate::mem::ptr::RawPtr; - use crate::mem::shared_mem::SharedMemory; - use crate::sandbox::SandboxConfiguration; - use crate::testing::bytes_for_path; - - #[test] - fn load_guest_binary_common() { - let guests = vec![ - rust_guest_as_pathbuf("simpleguest"), - rust_guest_as_pathbuf("callbackguest"), - ]; - for guest in guests { - let guest_bytes = bytes_for_path(guest).unwrap(); - let exe_info = ExeInfo::from_buf(guest_bytes.as_slice()).unwrap(); - let stack_size_override = 0x3000; - let heap_size_override = 0x10000; - let mut cfg = SandboxConfiguration::default(); - cfg.set_stack_size(stack_size_override); - cfg.set_heap_size(heap_size_override); - let (layout, shared_mem, _, _) = - super::load_guest_binary_common(cfg, &exe_info, |_, _| Ok(RawPtr::from(100))) - .unwrap(); - assert_eq!( - stack_size_override, - u64::try_from(layout.stack_size).unwrap() - ); - assert_eq!(heap_size_override, u64::try_from(layout.heap_size).unwrap()); - assert_eq!(layout.get_memory_size().unwrap(), shared_mem.mem_size()); - } - } -} diff --git a/src/hyperlight_host/src/mem/mod.rs b/src/hyperlight_host/src/mem/mod.rs index ca3bf522b..0f66ec6b8 100644 --- a/src/hyperlight_host/src/mem/mod.rs +++ b/src/hyperlight_host/src/mem/mod.rs @@ -14,9 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -/// Reusable structure to hold data and provide a `Drop` implementation -#[cfg(inprocess)] -pub(crate) mod custom_drop; /// A simple ELF loader pub(crate) mod elf; /// A generic wrapper for executable files (PE, ELF, etc) diff --git a/src/hyperlight_host/src/mem/shared_mem.rs b/src/hyperlight_host/src/mem/shared_mem.rs index 933918b4b..b976073b5 100644 --- a/src/hyperlight_host/src/mem/shared_mem.rs +++ b/src/hyperlight_host/src/mem/shared_mem.rs @@ -27,9 +27,7 @@ use tracing::{instrument, Span}; use windows::core::PCSTR; #[cfg(target_os = "windows")] use windows::Win32::Foundation::{CloseHandle, HANDLE, INVALID_HANDLE_VALUE}; -#[cfg(all(target_os = "windows", inprocess))] -use windows::Win32::System::Memory::FILE_MAP_EXECUTE; -#[cfg(all(target_os = "windows", not(inprocess)))] +#[cfg(target_os = "windows")] use windows::Win32::System::Memory::PAGE_READWRITE; #[cfg(target_os = "windows")] use windows::Win32::System::Memory::{ @@ -428,10 +426,7 @@ impl ExclusiveSharedMemory { // Allocate the memory use CreateFileMapping instead of VirtualAlloc // This allows us to map the memory into the surrogate process using MapViewOfFile2 - #[cfg(not(inprocess))] let flags = PAGE_READWRITE; - #[cfg(inprocess)] - let flags = PAGE_EXECUTE_READWRITE; let handle = unsafe { CreateFileMappingA( @@ -450,11 +445,7 @@ impl ExclusiveSharedMemory { )); } - #[cfg(not(inprocess))] let file_map = FILE_MAP_ALL_ACCESS; - #[cfg(inprocess)] - let file_map = FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE; - let addr = unsafe { MapViewOfFile(handle, file_map, 0, 0, 0) }; if addr.Value.is_null() { diff --git a/src/hyperlight_host/src/sandbox/leaked_outb.rs b/src/hyperlight_host/src/sandbox/leaked_outb.rs deleted file mode 100644 index e989eee8e..000000000 --- a/src/hyperlight_host/src/sandbox/leaked_outb.rs +++ /dev/null @@ -1,129 +0,0 @@ -/* -Copyright 2024 The Hyperlight Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -use std::os::raw::c_void; -use std::sync::{Arc, Mutex}; - -use tracing::{instrument, Span}; - -use crate::hypervisor::handlers::{OutBHandlerCaller, OutBHandlerWrapper}; -use crate::mem::custom_drop::CustomPtrDrop; -use crate::mem::mgr::SandboxMemoryManager; -use crate::mem::shared_mem::GuestSharedMemory; - -/// This function allows us to call the OutBHandler from the guest when running -/// in process. -/// -/// NOTE: This is not part of the C Hyperlight API , it is intended only to be -/// called in proc through a pointer passed to the guest. -extern "win64" fn call_outb( - ptr: *mut Arc>, - port: u16, - data_ptr: *const u8, - data_len: u64, -) { - let outb_handlercaller = unsafe { Box::from_raw(ptr) }; - let slice = unsafe { std::slice::from_raw_parts(data_ptr, data_len as usize) }; - let res = outb_handlercaller - .try_lock() - .map_err(|_| crate::new_error!("Error locking")) - .unwrap() - .call(port, slice.to_vec()); - // TODO, handle the case correctly when res is an error - assert!( - res.is_ok(), - "ERROR: The guest either panicked or returned an Error. Running inprocess-mode currently does not support error handling. " - ); - // Leak the box so that it is not dropped when the function returns - // the box will be dropped when the sandbox is dropped - Box::leak(outb_handlercaller); -} - -/// A container to store and safely drop leaked outb handlers when executing -/// with in-process mode on windows. -/// -/// -/// # Explanation of why we need to leak with this struct -/// -/// We need to leak the outb handler for in-process mode because, for this -/// execution mode, we need to write the address of an in-memory closure -/// (e.g. a `FnMut`) to memory, so the guest binary (which, again, is executing -/// in memory rather than in a hypervisor) can look up that address and make -/// function calls to the host. -/// -/// In this setup, however, Rust will drop the outb function before the guest -/// can make these calls, thus resulting in invalid memory accesses -/// (e.g. segmentation faults or whatever your favorite platform calls invalid -/// accesses). Thus, we need to leak the outb handler so it doesn't get -/// dropped before it's used. -/// -/// This struct also ensures that, when _it_ gets dropped -- which is later -/// than the contained `FnMut` would have been -- it properly cleans up -/// the previously-leaked memory. -/// -/// # Note for in-hypervisor mode or Linux -/// -/// If not executing with in-process mode, or not on windows, this struct -/// has no functionality. It's purposely available on windows and linux, -/// however, to ease internal implementation of the evolve methods. -/// -#[derive(Clone)] -pub(crate) struct LeakedOutBWrapper<'a> { - hdl_ptr: Arc>>, -} - -impl<'a> LeakedOutBWrapper<'a> { - #[instrument(skip_all, parent = Span::current(), level = "Trace")] - pub(crate) fn new( - mgr: &mut SandboxMemoryManager, - wrapper: OutBHandlerWrapper, - ) -> crate::Result { - let hdl_box = Box::new(wrapper.clone()); - let hdl_ptr = Box::into_raw(hdl_box); - let cd = CustomPtrDrop::new( - hdl_ptr, - Box::new(|ptr| { - let bx = unsafe { Box::from_raw(ptr) }; - drop(bx); - }), - ); - let res = Self { - hdl_ptr: Arc::new(Mutex::new(cd)), - }; - - let addr: u64 = res.hdl_wrapper_addr()?; - mgr.set_outb_address_and_context(Self::outb_addr(), addr)?; - Ok(res) - } - - /// Get the address to the internally-stored `OutBHandlerWrapper`. - /// - /// This pointer is referred to by the `SandboxMemoryManager` as - /// the outb "context" - #[instrument(err(Debug), skip_all, parent = Span::current(), level = "Trace")] - pub(super) fn hdl_wrapper_addr(&self) -> crate::Result { - let ptr = self - .hdl_ptr - .try_lock() - .map_err(|_| crate::new_error!("Error locking"))?; - Ok(ptr.as_mut_ptr() as u64) - } - - #[instrument(skip_all, parent = Span::current(), level = "Trace")] - pub(super) fn outb_addr() -> u64 { - call_outb as *const c_void as u64 - } -} diff --git a/src/hyperlight_host/src/sandbox/mem_mgr.rs b/src/hyperlight_host/src/sandbox/mem_mgr.rs index 8099b0991..84780db77 100644 --- a/src/hyperlight_host/src/sandbox/mem_mgr.rs +++ b/src/hyperlight_host/src/sandbox/mem_mgr.rs @@ -79,17 +79,12 @@ impl MemMgrWrapper { } #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")] - pub(super) fn write_memory_layout(&mut self, run_inprocess: bool) -> Result<()> { + pub(super) fn write_memory_layout(&mut self) -> Result<()> { let mgr = self.unwrap_mgr_mut(); let layout = mgr.layout; let shared_mem = mgr.get_shared_mem_mut(); let mem_size = shared_mem.mem_size(); - let guest_offset = if run_inprocess { - shared_mem.base_addr() - } else { - SandboxMemoryLayout::BASE_ADDRESS - }; - layout.write(shared_mem, guest_offset, mem_size, run_inprocess) + layout.write(shared_mem, SandboxMemoryLayout::BASE_ADDRESS, mem_size) } } diff --git a/src/hyperlight_host/src/sandbox/mod.rs b/src/hyperlight_host/src/sandbox/mod.rs index 6bc9c4a07..809d46811 100644 --- a/src/hyperlight_host/src/sandbox/mod.rs +++ b/src/hyperlight_host/src/sandbox/mod.rs @@ -23,12 +23,6 @@ pub(crate) mod hypervisor; /// Functionality for dealing with initialized sandboxes that can /// call 0 or more guest functions pub mod initialized_multi_use; -/// A container to leak, store and manage outb handlers for in-process -/// executions. On non-in-process executions (e.g. windows without -/// in-process mode turned on, or linux), the same container is just -/// a no-op -#[cfg(inprocess)] -pub(crate) mod leaked_outb; /// Functionality for dealing with memory access from the VM guest /// executable pub(crate) mod mem_access; diff --git a/src/hyperlight_host/src/sandbox/outb.rs b/src/hyperlight_host/src/sandbox/outb.rs index ee0d548d2..452533c76 100644 --- a/src/hyperlight_host/src/sandbox/outb.rs +++ b/src/hyperlight_host/src/sandbox/outb.rs @@ -204,22 +204,14 @@ mod tests { let new_mgr = || { let mut exe_info = simple_guest_exe_info().unwrap(); - let mut mgr = SandboxMemoryManager::load_guest_binary_into_memory( - sandbox_cfg, - &mut exe_info, - false, - ) - .unwrap(); + let mut mgr = + SandboxMemoryManager::load_guest_binary_into_memory(sandbox_cfg, &mut exe_info) + .unwrap(); let mem_size = mgr.get_shared_mem_mut().mem_size(); let layout = mgr.layout; let shared_mem = mgr.get_shared_mem_mut(); layout - .write( - shared_mem, - SandboxMemoryLayout::BASE_ADDRESS, - mem_size, - false, - ) + .write(shared_mem, SandboxMemoryLayout::BASE_ADDRESS, mem_size) .unwrap(); let (hmgr, _) = mgr.build(); hmgr @@ -324,22 +316,14 @@ mod tests { tracing::subscriber::with_default(subscriber.clone(), || { let new_mgr = || { let mut exe_info = simple_guest_exe_info().unwrap(); - let mut mgr = SandboxMemoryManager::load_guest_binary_into_memory( - sandbox_cfg, - &mut exe_info, - false, - ) - .unwrap(); + let mut mgr = + SandboxMemoryManager::load_guest_binary_into_memory(sandbox_cfg, &mut exe_info) + .unwrap(); let mem_size = mgr.get_shared_mem_mut().mem_size(); let layout = mgr.layout; let shared_mem = mgr.get_shared_mem_mut(); layout - .write( - shared_mem, - SandboxMemoryLayout::BASE_ADDRESS, - mem_size, - false, - ) + .write(shared_mem, SandboxMemoryLayout::BASE_ADDRESS, mem_size) .unwrap(); let (hmgr, _) = mgr.build(); hmgr diff --git a/src/hyperlight_host/src/sandbox/uninitialized.rs b/src/hyperlight_host/src/sandbox/uninitialized.rs index 7b973fef5..c8ecc9738 100644 --- a/src/hyperlight_host/src/sandbox/uninitialized.rs +++ b/src/hyperlight_host/src/sandbox/uninitialized.rs @@ -50,7 +50,6 @@ pub struct UninitializedSandbox { pub(crate) host_funcs: Arc>, /// The memory manager for the sandbox. pub(crate) mgr: MemMgrWrapper, - pub(crate) run_inprocess: bool, pub(crate) max_initialization_time: Duration, pub(crate) max_execution_time: Duration, pub(crate) max_wait_for_cancellation: Duration, @@ -150,36 +149,24 @@ impl UninitializedSandbox { buffer @ GuestBinary::Buffer(_) => buffer, }; - let run_opts = sandbox_run_options.unwrap_or_default(); - - let run_inprocess = run_opts.in_process(); - - if run_inprocess && cfg!(not(inprocess)) { - log_then_return!( - "Inprocess mode is only available in debug builds, and also requires cargo feature 'inprocess'" - ) - } - let sandbox_cfg = cfg.unwrap_or_default(); #[cfg(gdb)] let debug_info = sandbox_cfg.get_guest_debug_info(); let mut mem_mgr_wrapper = { - let mut mgr = - UninitializedSandbox::load_guest_binary(sandbox_cfg, &guest_binary, run_inprocess)?; + let mut mgr = UninitializedSandbox::load_guest_binary(sandbox_cfg, &guest_binary)?; let stack_guard = Self::create_stack_guard(); mgr.set_stack_guard(&stack_guard)?; MemMgrWrapper::new(mgr, stack_guard) }; - mem_mgr_wrapper.write_memory_layout(run_inprocess)?; + mem_mgr_wrapper.write_memory_layout()?; let host_funcs = Arc::new(Mutex::new(FunctionRegistry::default())); let mut sandbox = Self { host_funcs, mgr: mem_mgr_wrapper, - run_inprocess, max_initialization_time: Duration::from_millis( sandbox_cfg.get_max_initialization_time() as u64, ), @@ -263,14 +250,13 @@ impl UninitializedSandbox { pub(super) fn load_guest_binary( cfg: SandboxConfiguration, guest_binary: &GuestBinary, - inprocess: bool, ) -> Result> { let mut exe_info = match guest_binary { GuestBinary::FilePath(bin_path_str) => ExeInfo::from_file(bin_path_str)?, GuestBinary::Buffer(buffer) => ExeInfo::from_buf(buffer)?, }; - SandboxMemoryManager::load_guest_binary_into_memory(cfg, &mut exe_info, inprocess) + SandboxMemoryManager::load_guest_binary_into_memory(cfg, &mut exe_info) } /// Set the max log level to be used by the guest. @@ -354,32 +340,7 @@ mod tests { use crate::sandbox_state::sandbox::EvolvableSandbox; use crate::sandbox_state::transition::Noop; use crate::testing::log_values::{test_value_as_str, try_to_strings}; - use crate::{new_error, MultiUseSandbox, Result, SandboxRunOptions, UninitializedSandbox}; - - #[test] - fn test_in_process() { - let simple_guest_path = simple_guest_as_string().unwrap(); - let sbox = UninitializedSandbox::new( - GuestBinary::FilePath(simple_guest_path.clone()), - None, - Some(SandboxRunOptions::RunInProcess(false)), - None, - ); - - // in process should only be enabled with the inprocess feature and on debug builds - assert_eq!(sbox.is_ok(), cfg!(inprocess)); - - let simple_guest_path = simple_guest_as_string().unwrap(); - let sbox = UninitializedSandbox::new( - GuestBinary::FilePath(simple_guest_path.clone()), - None, - Some(SandboxRunOptions::RunInProcess(false)), - None, - ); - - // in process should only be enabled with the inprocess feature and on debug builds - assert_eq!(sbox.is_ok(), cfg!(all(inprocess))); - } + use crate::{new_error, MultiUseSandbox, Result, UninitializedSandbox}; #[test] fn test_new_sandbox() { @@ -452,12 +413,8 @@ mod tests { let simple_guest_path = simple_guest_as_string().unwrap(); - UninitializedSandbox::load_guest_binary( - cfg, - &GuestBinary::FilePath(simple_guest_path), - false, - ) - .unwrap(); + UninitializedSandbox::load_guest_binary(cfg, &GuestBinary::FilePath(simple_guest_path)) + .unwrap(); } #[test] diff --git a/src/hyperlight_host/src/sandbox_state/sandbox.rs b/src/hyperlight_host/src/sandbox_state/sandbox.rs index b6c172226..8731191ea 100644 --- a/src/hyperlight_host/src/sandbox_state/sandbox.rs +++ b/src/hyperlight_host/src/sandbox_state/sandbox.rs @@ -61,12 +61,6 @@ pub trait UninitializedSandbox: Sandbox { /// Retrieves mutable reference to strongly typed `UninitializedSandbox` fn get_uninitialized_sandbox_mut(&mut self) -> &mut crate::sandbox::UninitializedSandbox; - - /// Returns `true` if the Sandbox is configured to run in process otherwise `false` - #[instrument(skip_all, parent = Span::current(), level= "Trace")] - fn is_running_in_process(&self) -> bool { - self.get_uninitialized_sandbox().run_inprocess - } } /// A `Sandbox` that knows how to "evolve" into a next state. diff --git a/src/hyperlight_host/tests/common/mod.rs b/src/hyperlight_host/tests/common/mod.rs index 507b72b62..8240a1ef1 100644 --- a/src/hyperlight_host/tests/common/mod.rs +++ b/src/hyperlight_host/tests/common/mod.rs @@ -55,17 +55,6 @@ pub fn get_simpleguest_sandboxes( .unwrap() .evolve(Noop::default()) .unwrap(), - // in-process elf - #[cfg(inprocess)] - UninitializedSandbox::new( - GuestBinary::FilePath(elf_path.clone()), - None, - Some(hyperlight_host::SandboxRunOptions::RunInProcess(false)), - writer, - ) - .unwrap() - .evolve(Noop::default()) - .unwrap(), ] } @@ -78,15 +67,6 @@ pub fn get_callbackguest_uninit_sandboxes( // in hypervisor elf UninitializedSandbox::new(GuestBinary::FilePath(elf_path.clone()), None, None, writer) .unwrap(), - // in-process elf - #[cfg(inprocess)] - UninitializedSandbox::new( - GuestBinary::FilePath(elf_path.clone()), - None, - Some(hyperlight_host::SandboxRunOptions::RunInProcess(false)), - writer, - ) - .unwrap(), ] } diff --git a/src/hyperlight_host/tests/integration_test.rs b/src/hyperlight_host/tests/integration_test.rs index 7dcafce39..ad5f9710a 100644 --- a/src/hyperlight_host/tests/integration_test.rs +++ b/src/hyperlight_host/tests/integration_test.rs @@ -388,27 +388,11 @@ fn execute_on_stack() { .call_guest_function_by_name("ExecuteOnStack", ReturnType::String, Some(vec![])) .unwrap_err(); - #[cfg(inprocess)] - if let HyperlightError::Error(message) = result { - cfg_if::cfg_if! { - if #[cfg(target_os = "linux")] { - assert!(message.starts_with("Unexpected VM Exit") || message.starts_with("unknown Hyper-V run message type")); - } else if #[cfg(target_os = "windows")] { - assert!(message.starts_with("Unexpected VM Exit \"Did not receive a halt from Hypervisor as expected - Received WHV_RUN_VP_EXIT_REASON(4)")); - } else { - panic!("Unexpected"); - } - } - } - - #[cfg(not(inprocess))] - { - let err = result.to_string(); - assert!( - // exception that indicates a page fault - err.contains("PageFault") - ); - } + let err = result.to_string(); + assert!( + // exception that indicates a page fault + err.contains("PageFault") + ); } #[test] diff --git a/src/hyperlight_host/tests/sandbox_host_tests.rs b/src/hyperlight_host/tests/sandbox_host_tests.rs index 05f3a699c..801caa771 100644 --- a/src/hyperlight_host/tests/sandbox_host_tests.rs +++ b/src/hyperlight_host/tests/sandbox_host_tests.rs @@ -461,18 +461,7 @@ fn simple_test_helper() -> Result<()> { assert!(matches!(res3, Ok(ReturnValue::VecBytes(v)) if v == buffer)); } - let expected_calls = { - if cfg!(all(target_os = "windows", inprocess)) { - // windows debug build - 2 - } else if cfg!(inprocess) { - // linux debug build - 2 - } else { - // {windows,linux} release build - 1 - } - }; + let expected_calls = 1; assert_eq!( messages