From d034f19de4eeb78e4cb54657491d57d95d5bad3d Mon Sep 17 00:00:00 2001 From: Jorge Prendes Date: Fri, 21 Aug 2026 13:03:28 +0100 Subject: [PATCH 1/8] Let GuestBinary own its buffer `GuestBinary::Buffer` holds a `Vec`, so `GuestBinary` and `GuestEnvironment` carry no lifetime for the guest binary. A caller can hand its bytes over rather than keep them alive for as long as the sandbox. `ElfInfo` takes the payload by value, saving a copy of the guest binary when the bytes come from memory. Signed-off-by: Jorge Prendes --- CHANGELOG.md | 1 + src/hyperlight_host/src/mem/elf.rs | 44 +++++++++++-------- src/hyperlight_host/src/mem/exe.rs | 8 ++-- src/hyperlight_host/src/sandbox/builder.rs | 5 +-- .../src/sandbox/snapshot/mod.rs | 4 +- .../src/sandbox/uninitialized.rs | 28 ++++++------ 6 files changed, 49 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56a89482bc..ce2cdb70f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). resets to a clean default. On KVM the guest may only read or write declared MSRs, on MSHV and WHP this is not enforced. by @ludfjig in https://github.com/hyperlight-dev/hyperlight/pull/991 * **Breaking:** Filesystem paths are now represented using `PathBuf`. `GuestBinary::FilePath` now stores a `PathBuf` instead of a `String`, and `MultiUseSandbox::generate_crashdump_to_dir` accepts `Into` instead of `Into`. Callers passing a `String` to `GuestBinary::FilePath` must convert it using `.into()`. +* **Breaking:** `GuestBinary::Buffer` owns its bytes as a `Vec`, so `GuestBinary` no longer borrows and carries no lifetime parameter. * Deprecate `MultiUseSandbox::poisoned` in favor of `MultiUseSandbox::status().is_poisoned()`. Certain fixed guest addresses were changed on AArch64 to more easily diff --git a/src/hyperlight_host/src/mem/elf.rs b/src/hyperlight_host/src/mem/elf.rs index f6cde29068..cbd1485d8f 100644 --- a/src/hyperlight_host/src/mem/elf.rs +++ b/src/hyperlight_host/src/mem/elf.rs @@ -97,8 +97,9 @@ impl framehop::ModuleSectionInfo> for &UnwindInfo { } impl ElfInfo { - pub(crate) fn new(bytes: &[u8]) -> Result { - let elf = Elf::parse(bytes)?; + pub(crate) fn new(bytes: impl Into>) -> Result { + let bytes = bytes.into(); + let mut elf = Elf::parse(&bytes)?; let relocs = elf.dynrels.iter().chain(elf.dynrelas.iter()).collect(); if !elf .program_headers @@ -110,25 +111,32 @@ impl ElfInfo { // Look for the hyperlight version note embedded by // hyperlight-guest-bin. - let guest_bin_version = Self::read_version_note(&elf, bytes); + let guest_bin_version = Self::read_version_note(&elf, &bytes); + + let phdrs = std::mem::take(&mut elf.program_headers); + let entry = elf.entry; + #[cfg(feature = "mem_profile")] + let shdrs = elf + .section_headers + .iter() + .filter_map(|sh| { + Some(ResolvedSectionHeader { + name: elf.shdr_strtab.get_at(sh.sh_name)?.to_string(), + addr: sh.sh_addr, + offset: sh.sh_offset, + size: sh.sh_size, + }) + }) + .collect(); + + drop(elf); Ok(ElfInfo { - payload: bytes.to_vec(), - phdrs: elf.program_headers, + payload: bytes, + phdrs, #[cfg(feature = "mem_profile")] - shdrs: elf - .section_headers - .iter() - .filter_map(|sh| { - Some(ResolvedSectionHeader { - name: elf.shdr_strtab.get_at(sh.sh_name)?.to_string(), - addr: sh.sh_addr, - offset: sh.sh_offset, - size: sh.sh_size, - }) - }) - .collect(), - entry: elf.entry, + shdrs, + entry, relocs, guest_bin_version, }) diff --git a/src/hyperlight_host/src/mem/exe.rs b/src/hyperlight_host/src/mem/exe.rs index 7bf3a446d4..7adab74587 100644 --- a/src/hyperlight_host/src/mem/exe.rs +++ b/src/hyperlight_host/src/mem/exe.rs @@ -66,9 +66,9 @@ impl ExeInfo { let mut file = File::open(path)?; let mut contents = Vec::new(); file.read_to_end(&mut contents)?; - Self::from_buf(&contents) + Self::from_buf(contents) } - pub fn from_buf(buf: &[u8]) -> Result { + pub fn from_buf(buf: impl Into>) -> Result { ElfInfo::new(buf).map(ExeInfo::Elf) } pub fn entrypoint(&self) -> Offset { @@ -187,7 +187,7 @@ mod tests { fn patched_version_reports_mismatch() { let bytes = simpleguest_with_patched_version(); - let info = ExeInfo::from_buf(&bytes).expect("failed to load patched ELF"); + let info = ExeInfo::from_buf(bytes).expect("failed to load patched ELF"); assert_eq!(info.guest_bin_version(), Some("0.0.0")); assert_ne!( info.guest_bin_version().unwrap(), @@ -217,7 +217,7 @@ mod tests { let bytes = simpleguest_with_patched_version(); let result = crate::sandbox::snapshot::Snapshot::from_env( - crate::GuestBinary::Buffer(&bytes), + crate::GuestBinary::Buffer(bytes), crate::sandbox::SandboxConfiguration::default(), ); diff --git a/src/hyperlight_host/src/sandbox/builder.rs b/src/hyperlight_host/src/sandbox/builder.rs index e803a61eb0..9aa35eadff 100644 --- a/src/hyperlight_host/src/sandbox/builder.rs +++ b/src/hyperlight_host/src/sandbox/builder.rs @@ -95,9 +95,8 @@ impl SandboxBuilder { } /// Build a sandbox running the guest binary held in `buffer`. - pub fn build_from_bytes(self, buffer: impl AsRef<[u8]>) -> Result { - let buffer = buffer.as_ref(); - self.build_from_guest_binary(GuestBinary::Buffer(buffer)) + pub fn build_from_bytes(self, buffer: impl Into>) -> Result { + self.build_from_guest_binary(GuestBinary::Buffer(buffer.into())) } fn build_from_guest_binary(self, guest_binary: GuestBinary) -> Result { diff --git a/src/hyperlight_host/src/sandbox/snapshot/mod.rs b/src/hyperlight_host/src/sandbox/snapshot/mod.rs index a4def5b7af..2efa65d880 100644 --- a/src/hyperlight_host/src/sandbox/snapshot/mod.rs +++ b/src/hyperlight_host/src/sandbox/snapshot/mod.rs @@ -286,8 +286,8 @@ fn map_specials(pt_buf: &GuestPageTableBuffer, scratch_size: usize) { impl Snapshot { /// Create a new snapshot from the guest binary identified by `env`. With the configuration /// specified in `cfg`. - pub(crate) fn from_env<'a, 'b>( - env: impl Into>, + pub(crate) fn from_env<'b>( + env: impl Into>, cfg: SandboxConfiguration, ) -> Result { let env = env.into(); diff --git a/src/hyperlight_host/src/sandbox/uninitialized.rs b/src/hyperlight_host/src/sandbox/uninitialized.rs index 066c80c194..9caf3bd180 100644 --- a/src/hyperlight_host/src/sandbox/uninitialized.rs +++ b/src/hyperlight_host/src/sandbox/uninitialized.rs @@ -80,13 +80,13 @@ impl Debug for UninitializedSandbox { /// A `GuestBinary` is either a buffer or the file path to some data (e.g., a guest binary). #[derive(Debug)] -pub enum GuestBinary<'a> { +pub enum GuestBinary { /// A buffer containing the GuestBinary - Buffer(&'a [u8]), + Buffer(Vec), /// A path to the GuestBinary FilePath(PathBuf), } -impl<'a> GuestBinary<'a> { +impl GuestBinary { /// If the guest binary is identified by a file, canonicalise the path /// /// For [`GuestBinary::FilePath`], this resolves the path to its canonical @@ -128,16 +128,16 @@ impl<'a> From<&'a [u8]> for GuestBlob<'a> { /// This struct combines a guest binary (either from a file or memory buffer) with /// optional data that will be available to the guest during execution. #[derive(Debug)] -pub struct GuestEnvironment<'a, 'b> { +pub struct GuestEnvironment<'b> { /// The guest binary, which can be a file path or a buffer. - pub guest_binary: GuestBinary<'a>, + pub guest_binary: GuestBinary, /// An optional guest blob, which can be used to provide additional data to the guest. pub init_data: Option>, } -impl<'a, 'b> GuestEnvironment<'a, 'b> { +impl<'b> GuestEnvironment<'b> { /// Creates a new `GuestEnvironment` with the given guest binary and an optional guest blob. - pub fn new(guest_binary: GuestBinary<'a>, init_data: Option<&'b [u8]>) -> Self { + pub fn new(guest_binary: GuestBinary, init_data: Option<&'b [u8]>) -> Self { GuestEnvironment { guest_binary, init_data: init_data.map(GuestBlob::from), @@ -145,8 +145,8 @@ impl<'a, 'b> GuestEnvironment<'a, 'b> { } } -impl<'a> From> for GuestEnvironment<'a, '_> { - fn from(guest_binary: GuestBinary<'a>) -> Self { +impl From for GuestEnvironment<'_> { + fn from(guest_binary: GuestBinary) -> Self { GuestEnvironment { guest_binary, init_data: None, @@ -230,8 +230,8 @@ impl UninitializedSandbox { skip(env), parent = Span::current() )] - pub fn new<'a, 'b>( - env: impl Into>, + pub fn new<'b>( + env: impl Into>, cfg: Option, ) -> Result { let cfg = cfg.unwrap_or_default(); @@ -479,7 +479,7 @@ mod tests { let binary_path = simple_guest_as_pathbuf(); let sandbox = - UninitializedSandbox::new(GuestBinary::Buffer(&fs::read(binary_path).unwrap()), None); + UninitializedSandbox::new(GuestBinary::Buffer(fs::read(binary_path).unwrap()), None); assert!(sandbox.is_ok()); // Test with a invalid guest binary buffer @@ -487,7 +487,7 @@ mod tests { let binary_path = simple_guest_as_pathbuf(); let mut bytes = fs::read(binary_path).unwrap(); let _ = bytes.split_off(100); - let sandbox = UninitializedSandbox::new(GuestBinary::Buffer(&bytes), None); + let sandbox = UninitializedSandbox::new(GuestBinary::Buffer(bytes), None); assert!(sandbox.is_err()); } @@ -1275,7 +1275,7 @@ mod tests { let binary_bytes = fs::read(&binary_path).expect("Failed to read binary file"); let snapshot = Arc::new( - Snapshot::from_env(GuestBinary::Buffer(&binary_bytes), Default::default()) + Snapshot::from_env(GuestBinary::Buffer(binary_bytes), Default::default()) .expect("Failed to create snapshot from buffer"), ); From 15cb6d88ce681835a4a3e77bc4c3ff3c1dc32472 Mon Sep 17 00:00:00 2001 From: Jorge Prendes Date: Fri, 21 Aug 2026 13:03:41 +0100 Subject: [PATCH 2/8] Take the guest source at SandboxBuilder construction `SandboxBuilder::from_guest_file`, `from_guest_bytes` and `from_snapshot` name the source up front, and `build()` creates the sandbox. `guest_file`, `guest_bytes` and `guest_snapshot` set the source on an existing builder, so `new()` still serves callers that gather settings before the guest is known. The `build_from_*` methods become shorthand for naming a source and building in one call. Signed-off-by: Jorge Prendes --- src/hyperlight_host/src/sandbox/builder.rs | 272 ++++++++++++++------- 1 file changed, 187 insertions(+), 85 deletions(-) diff --git a/src/hyperlight_host/src/sandbox/builder.rs b/src/hyperlight_host/src/sandbox/builder.rs index 9aa35eadff..cbeafdef06 100644 --- a/src/hyperlight_host/src/sandbox/builder.rs +++ b/src/hyperlight_host/src/sandbox/builder.rs @@ -23,12 +23,34 @@ use crate::{ GuestBinary, HostFunctions, MultiUseSandbox as Sandbox, Result, UninitializedSandbox, new_error, }; +/// What a [`SandboxBuilder`] builds the sandbox from. +enum Source { + GuestBinary(GuestBinary), + Snapshot(Arc), +} + +impl Source { + fn guest_file(path: impl AsRef) -> Self { + Self::GuestBinary(GuestBinary::FilePath(path.as_ref().to_path_buf())) + } + + fn guest_bytes(buffer: impl Into>) -> Self { + Self::GuestBinary(GuestBinary::Buffer(buffer.into())) + } +} + /// Builds a [`Sandbox`]. /// -/// Start from [`SandboxBuilder::new`], chain the settings you need, then call -/// one of the `build_from_*` methods to create the sandbox from a guest binary -/// on disk, a guest binary in memory, or a [`Snapshot`]. Every setting has a -/// default, so a builder with no adjustments is valid. +/// Start from [`SandboxBuilder::from_guest_file`], +/// [`SandboxBuilder::from_guest_bytes`] or [`SandboxBuilder::from_snapshot`], +/// chain the settings you need, then call [`SandboxBuilder::build`]. Every +/// setting has a default, so a builder with no adjustments is valid. +/// +/// [`SandboxBuilder::new`] starts a builder with no guest, for when the +/// settings are gathered before the guest is known. +/// +/// By default only the `HostPrint` host function is registered, which writes +/// guest output to the host's stdout. Replace it with [`Self::host_print`]. /// /// # Examples /// @@ -37,10 +59,10 @@ use crate::{ /// ```no_run /// # use hyperlight_host::{Result, SandboxBuilder}; /// # fn example() -> Result<()> { -/// let mut sandbox = SandboxBuilder::new() +/// let mut sandbox = SandboxBuilder::from_guest_file("guest.bin") /// .heap_size(1024 * 1024) /// .host_function("Add", |a: i32, b: i32| a + b) -/// .build_from_file("guest.bin")?; +/// .build()?; /// /// let result: String = sandbox.call("Echo", "hello".to_string())?; /// # Ok(()) @@ -54,21 +76,21 @@ use crate::{ /// ```no_run /// # use hyperlight_host::{Result, SandboxBuilder}; /// # fn example() -> Result<()> { -/// let mut sandbox = SandboxBuilder::new() +/// let mut sandbox = SandboxBuilder::from_guest_file("guest.bin") /// .host_function("Add", |a: i32, b: i32| a + b) -/// .build_from_file("guest.bin")?; +/// .build()?; /// let snapshot = sandbox.snapshot()?; /// -/// let mut restored = SandboxBuilder::new() +/// let mut restored = SandboxBuilder::from_snapshot(snapshot) /// .host_function("Add", |a: i32, b: i32| a + b) -/// .build_from_snapshot(snapshot)?; +/// .build()?; /// /// let result: String = restored.call("Echo", "hello".to_string())?; /// # Ok(()) /// # } /// ``` -#[derive(Default)] pub struct SandboxBuilder { + source: Source, cfg: SandboxConfiguration, host_funcs: HostFunctions, init_data: Option<(Vec, MemoryRegionFlags)>, @@ -78,53 +100,109 @@ pub struct SandboxBuilder { } impl SandboxBuilder { - /// Create a builder with the default configuration and the default host - /// functions. + fn with_source(source: Source) -> Self { + Self { + source, + cfg: SandboxConfiguration::default(), + host_funcs: HostFunctions::default(), + init_data: None, + mapped_file_cow: Vec::new(), + mapped_memory_regions: Vec::new(), + guest_log_level: None, + } + } + + /// Create a builder with an empty guest binary. /// - /// By default only the `HostPrint` host function is registered, which - /// writes guest output to the host's stdout. Replace it with - /// [`Self::host_print`]. + /// Equivalent to `from_guest_bytes([])`. Useful to gather settings before + /// the guest is known. Name the source with [`Self::guest_file`], + /// [`Self::guest_bytes`] or [`Self::guest_snapshot`], otherwise + /// [`Self::build`] fails to parse the empty binary. pub fn new() -> Self { - Self::default() + Self::from_guest_bytes([]) } /// Build a sandbox running the guest binary at `path`. - pub fn build_from_file(self, path: impl AsRef) -> Result { - let path = path.as_ref().to_path_buf(); - self.build_from_guest_binary(GuestBinary::FilePath(path)) + pub fn from_guest_file(path: impl AsRef) -> Self { + Self::with_source(Source::guest_file(path)) } /// Build a sandbox running the guest binary held in `buffer`. - pub fn build_from_bytes(self, buffer: impl Into>) -> Result { - self.build_from_guest_binary(GuestBinary::Buffer(buffer.into())) + pub fn from_guest_bytes(buffer: impl Into>) -> Self { + Self::with_source(Source::guest_bytes(buffer)) } - fn build_from_guest_binary(self, guest_binary: GuestBinary) -> Result { - let init_data = self.init_data.as_ref().map(|(data, flags)| GuestBlob { - data, - permissions: *flags, - }); + /// Build a sandbox restored from `snapshot`. + pub fn from_snapshot(snapshot: Arc) -> Self { + Self::with_source(Source::Snapshot(snapshot)) + } - let env = GuestEnvironment { + /// Create the sandbox. + /// + /// # Errors + /// + /// When building from a snapshot, returns an error if [`Self::init_data`] + /// or [`Self::guest_log_level`] are set. The snapshot already carries + /// both, so they have no effect there. + pub fn build(self) -> Result { + let Self { + source, + cfg, + host_funcs, init_data, - guest_binary, + mapped_file_cow, + mapped_memory_regions, + guest_log_level, + } = self; + + let mut sandbox = match source { + Source::GuestBinary(guest_binary) => { + let env = GuestEnvironment { + init_data: init_data.as_ref().map(|(data, flags)| GuestBlob { + data, + permissions: *flags, + }), + guest_binary, + }; + + let mut uninitialized_sandbox = UninitializedSandbox::new(env, Some(cfg))?; + + uninitialized_sandbox.host_funcs = Arc::new(Mutex::new(host_funcs.into_inner())); + + for (path, guest_base) in mapped_file_cow { + uninitialized_sandbox.map_file_cow(&path, guest_base)?; + } + + if let Some(log_level) = guest_log_level { + uninitialized_sandbox.set_max_guest_log_level(log_level); + } + + uninitialized_sandbox.evolve()? + } + Source::Snapshot(snapshot) => { + if init_data.is_some() { + return Err(new_error!( + "init_data has no effect when building from a snapshot, as the snapshot already contains it" + )); + } + + if guest_log_level.is_some() { + return Err(new_error!( + "guest_log_level has no effect when building from a snapshot, as the snapshot already contains it" + )); + } + + let mut sandbox = Sandbox::from_snapshot(snapshot, host_funcs, Some(cfg))?; + + for (path, guest_base) in mapped_file_cow { + sandbox.map_file_cow(&path, guest_base)?; + } + + sandbox + } }; - let mut uninitialized_sandbox = UninitializedSandbox::new(env, Some(self.cfg))?; - - uninitialized_sandbox.host_funcs = Arc::new(Mutex::new(self.host_funcs.into_inner())); - - for (path, guest_base) in self.mapped_file_cow { - uninitialized_sandbox.map_file_cow(&path, guest_base)?; - } - - if let Some(log_level) = self.guest_log_level { - uninitialized_sandbox.set_max_guest_log_level(log_level); - } - - let mut sandbox = uninitialized_sandbox.evolve()?; - - for region in self.mapped_memory_regions { + for region in mapped_memory_regions { // SAFETY: the caller of `mapped_memory_region` guaranteed each region // stays valid and unmodified for the lifetime of this sandbox. unsafe { sandbox.map_region(®ion)? }; @@ -133,6 +211,16 @@ impl SandboxBuilder { Ok(sandbox) } + /// Build a sandbox running the guest binary at `path`. + pub fn build_from_file(self, path: impl AsRef) -> Result { + self.guest_file(path).build() + } + + /// Build a sandbox running the guest binary held in `buffer`. + pub fn build_from_bytes(self, buffer: impl Into>) -> Result { + self.guest_bytes(buffer).build() + } + /// Build a sandbox restored from `snapshot`. /// /// # Errors @@ -140,40 +228,43 @@ impl SandboxBuilder { /// Returns an error if [`Self::init_data`] or [`Self::guest_log_level`] /// are set. The snapshot already carries both, so they have no effect here. pub fn build_from_snapshot(self, snapshot: Arc) -> Result { - if self.init_data.is_some() { - return Err(new_error!( - "init_data has no effect when building from a snapshot, as the snapshot already contains it" - )); - } - - if self.guest_log_level.is_some() { - return Err(new_error!( - "guest_log_level has no effect when building from a snapshot, as the snapshot already contains it" - )); - } + self.guest_snapshot(snapshot).build() + } +} - let mut sandbox = Sandbox::from_snapshot(snapshot, self.host_funcs, Some(self.cfg))?; +impl Default for SandboxBuilder { + fn default() -> Self { + Self::new() + } +} - for (path, guest_base) in self.mapped_file_cow { - sandbox.map_file_cow(&path, guest_base)?; - } +impl SandboxBuilder { + /// Run the guest binary at `path`, replacing whatever source the builder + /// was created with. + pub fn guest_file(mut self, path: impl AsRef) -> Self { + self.source = Source::guest_file(path); + self + } - for region in self.mapped_memory_regions { - // SAFETY: the caller of `mapped_memory_region` guaranteed each region - // stays valid and unmodified for the lifetime of this sandbox. - unsafe { sandbox.map_region(®ion)? }; - } + /// Run the guest binary held in `buffer`, replacing whatever source the + /// builder was created with. + pub fn guest_bytes(mut self, buffer: impl Into>) -> Self { + self.source = Source::guest_bytes(buffer); + self + } - Ok(sandbox) + /// Restore from `snapshot`, replacing whatever source the builder was + /// created with. + pub fn guest_snapshot(mut self, snapshot: Arc) -> Self { + self.source = Source::Snapshot(snapshot); + self } -} -impl SandboxBuilder { /// Sets the sandbox `init_data` into the sandbox's memory when it is built, with `flags` as /// the guest's permissions on that region. /// - /// Note: [`Self::build_from_snapshot`] errors if this setting is set, as the snapshot already - /// contains the init data. + /// Note: [`Self::build`] errors if this setting is set on a builder created + /// with [`Self::from_snapshot`], as the snapshot already contains the init data. pub fn init_data(mut self, data: impl Into>, flags: MemoryRegionFlags) -> Self { self.init_data = Some((data.into(), flags)); self @@ -183,8 +274,8 @@ impl SandboxBuilder { /// copy-on-write. /// /// `guest_base` must be page-aligned and lie outside the sandbox's primary - /// shared memory region. Violations surface as an error from the - /// `build_from_*` call, not here. Call this once per file to map several. + /// shared memory region. Violations surface as an error from + /// [`Self::build`], not here. Call this once per file to map several. pub fn mapped_file_cow(mut self, path: impl AsRef, guest_base: u64) -> Self { self.mapped_file_cow .push((path.as_ref().to_path_buf(), guest_base)); @@ -211,8 +302,8 @@ impl SandboxBuilder { /// If not set, the log level is determined by the `RUST_LOG` environment variable, /// defaulting to [`LevelFilter::ERROR`] if unset. /// - /// Note: [`Self::build_from_snapshot`] errors if this setting is set, as the log level is - /// already captured in the snapshot. + /// Note: [`Self::build`] errors if this setting is set on a builder created + /// with [`Self::from_snapshot`], as the log level is already captured in the snapshot. pub fn guest_log_level(mut self, level: LevelFilter) -> Self { self.guest_log_level = Some(level); self @@ -407,11 +498,11 @@ mod tests { use crate::mem::memory_region::MemoryRegionFlags; #[test] - fn build_from_file() { + fn build_from_guest_file() { let path = simple_guest_as_string().unwrap(); - let mut sandbox = SandboxBuilder::new() + let mut sandbox = SandboxBuilder::from_guest_file(path) .input_data_size(0x8000) - .build_from_file(path) + .build() .unwrap(); let result = sandbox.call::("Echo", "hello".to_string()).unwrap(); @@ -419,9 +510,20 @@ mod tests { } #[test] - fn build_from_bytes() { + fn build_from_guest_bytes() { let bytes = std::fs::read(simple_guest_as_string().unwrap()).unwrap(); - let mut sandbox = SandboxBuilder::new().build_from_bytes(bytes).unwrap(); + let mut sandbox = SandboxBuilder::from_guest_bytes(bytes).build().unwrap(); + + let result = sandbox.call::("Echo", "hello".to_string()).unwrap(); + assert_eq!(result, "hello"); + } + + #[test] + fn build_from_new_needs_a_guest() { + assert!(SandboxBuilder::new().build().is_err()); + + let path = simple_guest_as_string().unwrap(); + let mut sandbox = SandboxBuilder::new().guest_file(path).build().unwrap(); let result = sandbox.call::("Echo", "hello".to_string()).unwrap(); assert_eq!(result, "hello"); @@ -430,10 +532,10 @@ mod tests { #[test] fn build_from_snapshot() { let path = simple_guest_as_string().unwrap(); - let mut sandbox = SandboxBuilder::new().build_from_file(path).unwrap(); + let mut sandbox = SandboxBuilder::from_guest_file(path).build().unwrap(); let snapshot = sandbox.snapshot().unwrap(); - let mut restored = SandboxBuilder::new().build_from_snapshot(snapshot).unwrap(); + let mut restored = SandboxBuilder::from_snapshot(snapshot).build().unwrap(); let result = restored .call::("Echo", "hello".to_string()) @@ -444,20 +546,20 @@ mod tests { #[test] fn build_from_snapshot_errors_on_ignored_settings() { let path = simple_guest_as_string().unwrap(); - let mut sandbox = SandboxBuilder::new().build_from_file(path).unwrap(); + let mut sandbox = SandboxBuilder::from_guest_file(path).build().unwrap(); let snapshot = sandbox.snapshot().unwrap(); assert!( - SandboxBuilder::new() + SandboxBuilder::from_snapshot(snapshot.clone()) .init_data([0u8; 8], MemoryRegionFlags::READ) - .build_from_snapshot(snapshot.clone()) + .build() .is_err() ); assert!( - SandboxBuilder::new() + SandboxBuilder::from_snapshot(snapshot) .guest_log_level(LevelFilter::INFO) - .build_from_snapshot(snapshot) + .build() .is_err() ); } From 2da264664611f0af1591f27377d59e2f3b6eb8f5 Mon Sep 17 00:00:00 2001 From: Jorge Prendes Date: Fri, 21 Aug 2026 13:43:37 +0100 Subject: [PATCH 3/8] Use the SandboxBuilder guest source constructors Name the guest binary or snapshot when creating the builder, then call `build()`. Helpers that hand out a preconfigured builder carry their guest with them, and the test helpers take a closure that configures the builder rather than a builder value. Signed-off-by: Jorge Prendes --- README.md | 4 +- docs/how-to-debug-a-hyperlight-guest.md | 4 +- fuzz/fuzz_targets/guest_call.rs | 4 +- fuzz/fuzz_targets/guest_trace.rs | 4 +- fuzz/fuzz_targets/host_call.rs | 4 +- fuzz/fuzz_targets/host_print.rs | 4 +- src/hyperlight_host/benches/benchmarks.rs | 18 +- .../examples/crashdump/main.rs | 18 +- src/hyperlight_host/examples/func_ctx/main.rs | 2 +- .../examples/guest-debugging/main.rs | 22 +- .../examples/hello-world/main.rs | 13 +- src/hyperlight_host/examples/logging/main.rs | 6 +- .../examples/map-file-cow-test/main.rs | 11 +- src/hyperlight_host/examples/metrics/main.rs | 8 +- .../examples/tracing-chrome/main.rs | 2 +- .../examples/tracing-otlp/main.rs | 4 +- src/hyperlight_host/examples/tracing/main.rs | 6 +- src/hyperlight_host/src/metrics/mod.rs | 4 +- src/hyperlight_host/src/sandbox/host_funcs.rs | 6 +- .../src/sandbox/initialized_multi_use.rs | 396 +++++++++--------- .../src/sandbox/snapshot/file/mod.rs | 2 +- .../src/sandbox/snapshot/file_tests.rs | 56 +-- src/hyperlight_host/tests/common/mod.rs | 42 +- src/hyperlight_host/tests/integration_test.rs | 85 ++-- .../tests/sandbox_host_tests.rs | 24 +- .../tests/snapshot_goldens/checks.rs | 12 +- .../tests/snapshot_goldens/fixtures.rs | 4 +- 27 files changed, 395 insertions(+), 370 deletions(-) diff --git a/README.md b/README.md index f8942fd6de..4a1b401e1e 100644 --- a/README.md +++ b/README.md @@ -24,9 +24,9 @@ Hyperlight lets you safely run untrusted code inside hypervisor-isolated micro V // Build a sandbox from a guest binary, registering a host function the guest // can call. In a real app that function might query a database, read a config, // or call an external API. By default, guests can only print to the host. -let mut sandbox = SandboxBuilder::new() +let mut sandbox = SandboxBuilder::from_guest_file(guest_path) .host_function("GetWeekday", || Ok("Monday".to_string())) - .build_from_file(guest_path)?; + .build()?; // Call a function inside the VM let greeting: String = sandbox.call("SayHello", "World".to_string())?; diff --git a/docs/how-to-debug-a-hyperlight-guest.md b/docs/how-to-debug-a-hyperlight-guest.md index 2983053139..1f1af78f98 100644 --- a/docs/how-to-debug-a-hyperlight-guest.md +++ b/docs/how-to-debug-a-hyperlight-guest.md @@ -222,9 +222,9 @@ The name and location of the dump file will be printed to the console and logged **NOTE**: By enabling the `crashdump` feature, you instruct Hyperlight to create core dump files for all sandboxes when an unhandled crash occurs. To selectively disable this feature for a specific sandbox, call `guest_core_dump(false)` on the `SandboxBuilder`. ```rust - let sandbox = SandboxBuilder::new() + let sandbox = SandboxBuilder::from_guest_file(guest_path) .guest_core_dump(false) // Disable core dump for this sandbox - .build_from_file(guest_path)?; + .build()?; ``` ## Creating a dump on demand diff --git a/fuzz/fuzz_targets/guest_call.rs b/fuzz/fuzz_targets/guest_call.rs index e1e37e2784..64a0c6ffc9 100644 --- a/fuzz/fuzz_targets/guest_call.rs +++ b/fuzz/fuzz_targets/guest_call.rs @@ -15,8 +15,8 @@ static SANDBOX: OnceLock> = OnceLock::new(); // For fuzzing efficiency, we create one Sandbox and reuse it for all fuzzing iterations. fuzz_target!( init: { - let mu_sbox = SandboxBuilder::new() - .build_from_file(simple_guest_for_fuzzing_as_pathbuf()) + let mu_sbox = SandboxBuilder::from_guest_file(simple_guest_for_fuzzing_as_pathbuf()) + .build() .unwrap(); SANDBOX.set(Mutex::new(mu_sbox)).unwrap(); }, diff --git a/fuzz/fuzz_targets/guest_trace.rs b/fuzz/fuzz_targets/guest_trace.rs index c39df9a486..202cb4eb73 100644 --- a/fuzz/fuzz_targets/guest_trace.rs +++ b/fuzz/fuzz_targets/guest_trace.rs @@ -54,9 +54,9 @@ impl<'a> Arbitrary<'a> for FuzzInput { fuzz_target!( init: { // In local tests, 256 KiB seemed sufficient for deep recursion - let mu_sbox = SandboxBuilder::new() + let mu_sbox = SandboxBuilder::from_guest_file(simple_guest_for_fuzzing_as_pathbuf()) .scratch_size(256 * 1024) - .build_from_file(simple_guest_for_fuzzing_as_pathbuf()) + .build() .unwrap(); SANDBOX.set(Mutex::new(mu_sbox)).unwrap(); diff --git a/fuzz/fuzz_targets/host_call.rs b/fuzz/fuzz_targets/host_call.rs index 82ecdce5b3..e390218aec 100644 --- a/fuzz/fuzz_targets/host_call.rs +++ b/fuzz/fuzz_targets/host_call.rs @@ -17,11 +17,11 @@ static SANDBOX: OnceLock> = OnceLock::new(); // For fuzzing efficiency, we create one Sandbox and reuse it for all fuzzing iterations. fuzz_target!( init: { - let mu_sbox = SandboxBuilder::new() + let mu_sbox = SandboxBuilder::from_guest_file(simple_guest_for_fuzzing_as_pathbuf()) .output_data_size(64 * 1024) // 64 KB output buffer .input_data_size(64 * 1024) // 64 KB input buffer .scratch_size(512 * 1024) // large scratch region to contain those buffers, any data copies, etc. - .build_from_file(simple_guest_for_fuzzing_as_pathbuf()) + .build() .unwrap(); SANDBOX.set(Mutex::new(mu_sbox)).unwrap(); }, diff --git a/fuzz/fuzz_targets/host_print.rs b/fuzz/fuzz_targets/host_print.rs index 89ccc1dfcf..10b52f942f 100644 --- a/fuzz/fuzz_targets/host_print.rs +++ b/fuzz/fuzz_targets/host_print.rs @@ -14,8 +14,8 @@ static SANDBOX: OnceLock> = OnceLock::new(); // For fuzzing efficiency, we create one Sandbox and reuse it for all fuzzing iterations. fuzz_target!( init: { - let mu_sbox = SandboxBuilder::new() - .build_from_file(simple_guest_for_fuzzing_as_pathbuf()) + let mu_sbox = SandboxBuilder::from_guest_file(simple_guest_for_fuzzing_as_pathbuf()) + .build() .unwrap(); SANDBOX.set(Mutex::new(mu_sbox)).unwrap(); }, diff --git a/src/hyperlight_host/benches/benchmarks.rs b/src/hyperlight_host/benches/benchmarks.rs index befe46fa37..03c3b85ae5 100644 --- a/src/hyperlight_host/benches/benchmarks.rs +++ b/src/hyperlight_host/benches/benchmarks.rs @@ -31,9 +31,9 @@ enum SandboxSize { } impl SandboxSize { - /// Returns a builder configured for this sandbox size. + /// Returns a builder for the simple guest, configured for this sandbox size. fn builder(&self) -> SandboxBuilder { - let builder = SandboxBuilder::new(); + let builder = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()); match self { Self::Default => builder, Self::Small => builder.heap_size(SMALL_HEAP_SIZE), @@ -59,9 +59,7 @@ impl SandboxSize { } fn create_multiuse_sandbox_with_size(size: SandboxSize) -> MultiUseSandbox { - size.builder() - .build_from_file(simple_guest_as_pathbuf()) - .unwrap() + size.builder().build().unwrap() } // ============================================================================ @@ -132,7 +130,7 @@ fn bench_guest_call_with_host_function(b: &mut criterion::Bencher, size: Sandbox let mut multiuse_sandbox = size .builder() .host_function("HostAdd", |a: i32, b: i32| Ok(a + b)) - .build_from_file(simple_guest_as_pathbuf()) + .build() .unwrap(); b.iter(|| { @@ -352,13 +350,13 @@ fn guest_call_benchmark_large_param(c: &mut Criterion) { let large_vec = vec![0u8; SIZE]; let large_string = String::from_utf8(large_vec.clone()).unwrap(); - let mut sandbox = SandboxBuilder::new() + let mut sandbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) // 2 * SIZE + 1 MB, to allow 1MB for the rest of the serialized function call .input_data_size(2 * SIZE + (1024 * 1024)) .heap_size(SIZE as u64 * 15) // Big enough for the IO data regions and enough of the heap to be used .scratch_size(6 * SIZE + 4 * (1024 * 1024)) - .build_from_file(simple_guest_as_pathbuf()) + .build() .unwrap(); b.iter_with_setup( @@ -434,9 +432,9 @@ fn sample_workloads_benchmark(c: &mut Criterion) { let mut group = c.benchmark_group("sample_workloads"); fn bench_24k_in_8k_out(b: &mut criterion::Bencher, guest_path: std::path::PathBuf) { - let mut sandbox = SandboxBuilder::new() + let mut sandbox = SandboxBuilder::from_guest_file(guest_path) .input_data_size(25 * 1024) - .build_from_file(guest_path) + .build() .unwrap(); b.iter_with_setup( diff --git a/src/hyperlight_host/examples/crashdump/main.rs b/src/hyperlight_host/examples/crashdump/main.rs index fbd7eddcca..a85dde6366 100644 --- a/src/hyperlight_host/examples/crashdump/main.rs +++ b/src/hyperlight_host/examples/crashdump/main.rs @@ -126,7 +126,7 @@ fn main() -> hyperlight_host::Result<()> { /// 4. The crash dump is written automatically (no explicit call needed) #[cfg(all(crashdump, target_os = "linux"))] fn guest_crash_auto_dump(guest_path: &Path) -> hyperlight_host::Result<()> { - let mut sandbox = SandboxBuilder::new().build_from_file(guest_path)?; + let mut sandbox = SandboxBuilder::from_guest_file(guest_path).build()?; // Map a file as read-only into the guest at a known address. let mapping_file = create_mapping_file(); @@ -186,7 +186,7 @@ fn create_mapping_file() -> std::path::PathBuf { /// fault), the automatic crash dump code in the VM run loop is not reached. /// To get a crash dump in this case, call `generate_crashdump()` explicitly. fn guest_crash_with_on_demand_dump(guest_path: &Path) -> hyperlight_host::Result<()> { - let mut sandbox = SandboxBuilder::new().build_from_file(guest_path)?; + let mut sandbox = SandboxBuilder::from_guest_file(guest_path).build()?; // This call triggers a ud2 instruction in the guest. The guest's IDT // catches the #UD exception and reports it back to the host as a @@ -224,9 +224,9 @@ fn guest_crash_with_on_demand_dump(guest_path: &Path) -> hyperlight_host::Result fn guest_crash_with_dump_disabled(guest_path: &Path) -> hyperlight_host::Result<()> { println!("Core dump disabled for this sandbox."); - let mut sandbox = SandboxBuilder::new() + let mut sandbox = SandboxBuilder::from_guest_file(guest_path) .guest_core_dump(false) - .build_from_file(guest_path)?; + .build()?; let mapping_file = create_mapping_file(); let guest_base: u64 = 0x200000000; @@ -360,7 +360,7 @@ mod tests { // Create sandbox with default config (crashdump enabled) let guest_path = hyperlight_testing::simple_guest_as_pathbuf(); - let mut sbox = SandboxBuilder::new().build_from_file(guest_path).unwrap(); + let mut sbox = SandboxBuilder::from_guest_file(guest_path).build().unwrap(); // Map an additional test file into the guest at a known address. // The core dump already includes snapshot and scratch regions @@ -429,16 +429,16 @@ mod tests { /// sandboxes resolve symbols the same way as directly-evolved ones. fn generate_crashdump_from_snapshot(dump_dir: &Path) -> PathBuf { let guest_path = hyperlight_testing::simple_guest_as_pathbuf(); - let mut sbox = SandboxBuilder::new() + let mut sbox = SandboxBuilder::from_guest_file(guest_path) .guest_core_dump(true) - .build_from_file(guest_path) + .build() .unwrap(); let snapshot = sbox.snapshot().expect("snapshot"); - let mut sbox2 = SandboxBuilder::new() + let mut sbox2 = SandboxBuilder::from_snapshot(snapshot) .guest_core_dump(true) - .build_from_snapshot(snapshot) + .build() .unwrap(); let result = sbox2.call::<()>("TriggerException", ()); diff --git a/src/hyperlight_host/examples/func_ctx/main.rs b/src/hyperlight_host/examples/func_ctx/main.rs index 0199b47459..a36f62c7c3 100644 --- a/src/hyperlight_host/examples/func_ctx/main.rs +++ b/src/hyperlight_host/examples/func_ctx/main.rs @@ -8,7 +8,7 @@ fn main() { // create a new `MultiUseSandbox` configured to run the `simpleguest.exe` // test guest binary let path = simple_guest_as_pathbuf(); - let mut sbox = SandboxBuilder::new().build_from_file(path).unwrap(); + let mut sbox = SandboxBuilder::from_guest_file(path).build().unwrap(); // Do several calls against a sandbox running the `simpleguest.exe` binary, // and print their results diff --git a/src/hyperlight_host/examples/guest-debugging/main.rs b/src/hyperlight_host/examples/guest-debugging/main.rs index 847e7186a6..b7bd2fc1de 100644 --- a/src/hyperlight_host/examples/guest-debugging/main.rs +++ b/src/hyperlight_host/examples/guest-debugging/main.rs @@ -8,7 +8,7 @@ use hyperlight_host::sandbox::config::DebugInfo; /// Build a sandbox builder that enables GDB debugging when the `gdb` feature is enabled. fn debuggable_builder() -> SandboxBuilder { - let builder = SandboxBuilder::new(); + let builder = SandboxBuilder::from_guest_file(hyperlight_testing::simple_guest_as_pathbuf()); #[cfg(gdb)] let builder = builder.guest_debug_info(DebugInfo { port: 8080 }); @@ -26,12 +26,13 @@ fn main() -> hyperlight_host::Result<()> { // Build a sandbox with a guest binary and debug enabled let mut multi_use_sandbox_dbg = debuggable_builder() .host_function("Sleep5Secs", sleep_5_secs) - .build_from_file(hyperlight_testing::simple_guest_as_pathbuf())?; + .build()?; // Build a sandbox with a guest binary - let mut multi_use_sandbox = SandboxBuilder::new() - .host_function("Sleep5Secs", sleep_5_secs) - .build_from_file(hyperlight_testing::simple_guest_as_pathbuf())?; + let mut multi_use_sandbox = + SandboxBuilder::from_guest_file(hyperlight_testing::simple_guest_as_pathbuf()) + .host_function("Sleep5Secs", sleep_5_secs) + .build()?; // Call guest function multi_use_sandbox_dbg @@ -338,9 +339,10 @@ mod tests { let (out_file_path, cmd_file_path, manifest_dir) = gdb_test_paths("gdb-from-snapshot"); // Build a sandbox the normal way and snapshot it in-memory. - let mut producer = SandboxBuilder::new() - .build_from_file(hyperlight_testing::simple_guest_as_pathbuf()) - .unwrap(); + let mut producer = + SandboxBuilder::from_guest_file(hyperlight_testing::simple_guest_as_pathbuf()) + .build() + .unwrap(); let snap = producer.snapshot().unwrap(); // Order matters. The gdb stub event loop must enter (i.e. @@ -353,9 +355,9 @@ mod tests { // here before the client is launched below. let snap_thread = snap.clone(); let sandbox_thread = thread::spawn(move || -> Result<()> { - let mut sbox = SandboxBuilder::new() + let mut sbox = SandboxBuilder::from_snapshot(snap_thread) .guest_debug_info(DebugInfo { port: PORT }) - .build_from_snapshot(snap_thread)?; + .build()?; sbox.call::( "PrintOutput", "Hello from a from_snapshot sandbox\n".to_string(), diff --git a/src/hyperlight_host/examples/hello-world/main.rs b/src/hyperlight_host/examples/hello-world/main.rs index 2b35664009..7f5dd181fd 100644 --- a/src/hyperlight_host/examples/hello-world/main.rs +++ b/src/hyperlight_host/examples/hello-world/main.rs @@ -7,12 +7,13 @@ use hyperlight_host::SandboxBuilder; fn main() -> hyperlight_host::Result<()> { // Build a sandbox running a guest binary, with a host function registered. // Note: the host function is unused, it's just here for demonstration purposes - let mut sandbox = SandboxBuilder::new() - .host_function("Sleep5Secs", || { - thread::sleep(std::time::Duration::from_secs(5)); - Ok(()) - }) - .build_from_file(hyperlight_testing::simple_guest_as_pathbuf())?; + let mut sandbox = + SandboxBuilder::from_guest_file(hyperlight_testing::simple_guest_as_pathbuf()) + .host_function("Sleep5Secs", || { + thread::sleep(std::time::Duration::from_secs(5)); + Ok(()) + }) + .build()?; // Call guest function let message = "Hello, World! I am executing inside of a VM :)\n".to_string(); diff --git a/src/hyperlight_host/examples/logging/main.rs b/src/hyperlight_host/examples/logging/main.rs index c6ca53dbb8..bcce27afd2 100644 --- a/src/hyperlight_host/examples/logging/main.rs +++ b/src/hyperlight_host/examples/logging/main.rs @@ -25,9 +25,9 @@ fn main() -> Result<()> { let path = hyperlight_guest_path.clone(); let res: Result<()> = { // Create a new sandbox. - let mut multiuse_sandbox = SandboxBuilder::new() + let mut multiuse_sandbox = SandboxBuilder::from_guest_file(path) .host_print(fn_writer) - .build_from_file(path)?; + .build()?; // Call a guest function 5 times to generate some log entries. for _ in 0..5 { @@ -54,7 +54,7 @@ fn main() -> Result<()> { // Create a new sandbox. let mut multiuse_sandbox = - SandboxBuilder::new().build_from_file(hyperlight_guest_path.clone())?; + SandboxBuilder::from_guest_file(hyperlight_guest_path.clone()).build()?; let interrupt_handle = multiuse_sandbox.interrupt_handle(); let barrier = Arc::new(Barrier::new(2)); let barrier2 = barrier.clone(); diff --git a/src/hyperlight_host/examples/map-file-cow-test/main.rs b/src/hyperlight_host/examples/map-file-cow-test/main.rs index 9f4a4dd46c..c9dcaab254 100644 --- a/src/hyperlight_host/examples/map-file-cow-test/main.rs +++ b/src/hyperlight_host/examples/map-file-cow-test/main.rs @@ -20,11 +20,12 @@ use std::path::Path; use hyperlight_host::SandboxBuilder; fn run_once(test_file: &Path, label: &str) -> hyperlight_host::Result<()> { - let mut sandbox = SandboxBuilder::new() - .heap_size(4 * 1024 * 1024) - .scratch_size(64 * 1024 * 1024) - .mapped_file_cow(test_file, 0xC000_0000) - .build_from_file(hyperlight_testing::simple_guest_as_pathbuf())?; + let mut sandbox = + SandboxBuilder::from_guest_file(hyperlight_testing::simple_guest_as_pathbuf()) + .heap_size(4 * 1024 * 1024) + .scratch_size(64 * 1024 * 1024) + .mapped_file_cow(test_file, 0xC000_0000) + .build()?; eprintln!( "[{label}] sandbox built with a {} byte file mapped", std::fs::metadata(test_file)?.len() diff --git a/src/hyperlight_host/examples/metrics/main.rs b/src/hyperlight_host/examples/metrics/main.rs index 0d1480645c..13488a2b72 100644 --- a/src/hyperlight_host/examples/metrics/main.rs +++ b/src/hyperlight_host/examples/metrics/main.rs @@ -36,9 +36,9 @@ fn do_hyperlight_stuff() { let path = hyperlight_guest_path.clone(); let handle = spawn(move || -> Result<()> { // Create a new sandbox. - let mut multiuse_sandbox = SandboxBuilder::new() + let mut multiuse_sandbox = SandboxBuilder::from_guest_file(path) .host_print(fn_writer) - .build_from_file(path)?; + .build()?; // Call a guest function 5 times to generate some metrics. for _ in 0..5 { @@ -64,8 +64,8 @@ fn do_hyperlight_stuff() { } // Create a new sandbox. - let mut multiuse_sandbox = SandboxBuilder::new() - .build_from_file(hyperlight_guest_path.clone()) + let mut multiuse_sandbox = SandboxBuilder::from_guest_file(hyperlight_guest_path.clone()) + .build() .expect("Failed to build sandbox"); let interrupt_handle = multiuse_sandbox.interrupt_handle(); diff --git a/src/hyperlight_host/examples/tracing-chrome/main.rs b/src/hyperlight_host/examples/tracing-chrome/main.rs index 7f4183d8d4..4fc474bb89 100644 --- a/src/hyperlight_host/examples/tracing-chrome/main.rs +++ b/src/hyperlight_host/examples/tracing-chrome/main.rs @@ -14,7 +14,7 @@ fn main() -> Result<()> { let simple_guest_path = simple_guest_as_pathbuf(); // Create a new sandbox. - let mut sbox = SandboxBuilder::new().build_from_file(simple_guest_path)?; + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_path).build()?; // do the function call let current_time = std::time::Instant::now(); diff --git a/src/hyperlight_host/examples/tracing-otlp/main.rs b/src/hyperlight_host/examples/tracing-otlp/main.rs index d8f1e61252..b3d77c5af7 100644 --- a/src/hyperlight_host/examples/tracing-otlp/main.rs +++ b/src/hyperlight_host/examples/tracing-otlp/main.rs @@ -109,9 +109,9 @@ fn run_example(wait_input: bool) -> HyperlightResult<()> { let _entered = span.enter(); // Create a new sandbox. - let mut multiuse_sandbox = SandboxBuilder::new() + let mut multiuse_sandbox = SandboxBuilder::from_guest_file(path.clone()) .host_print(fn_writer) - .build_from_file(path.clone())?; + .build()?; // Call a guest function 5 times to generate some log entries. for _ in 0..5 { diff --git a/src/hyperlight_host/examples/tracing/main.rs b/src/hyperlight_host/examples/tracing/main.rs index dfd2ba5e12..55766925ce 100644 --- a/src/hyperlight_host/examples/tracing/main.rs +++ b/src/hyperlight_host/examples/tracing/main.rs @@ -53,9 +53,9 @@ fn run_example() -> Result<()> { let _entered = span.enter(); // Create a new sandbox. - let mut multiuse_sandbox = SandboxBuilder::new() + let mut multiuse_sandbox = SandboxBuilder::from_guest_file(path) .host_print(fn_writer) - .build_from_file(path)?; + .build()?; // Call a guest function 5 times to generate some log entries. for _ in 0..5 { @@ -81,7 +81,7 @@ fn run_example() -> Result<()> { // Create a new sandbox. let mut multiuse_sandbox = - SandboxBuilder::new().build_from_file(hyperlight_guest_path.clone())?; + SandboxBuilder::from_guest_file(hyperlight_guest_path.clone()).build()?; let interrupt_handle = multiuse_sandbox.interrupt_handle(); // Call a function that gets cancelled by the host function 5 times to generate some log entries. diff --git a/src/hyperlight_host/src/metrics/mod.rs b/src/hyperlight_host/src/metrics/mod.rs index 015e159e5e..fa3e72f79f 100644 --- a/src/hyperlight_host/src/metrics/mod.rs +++ b/src/hyperlight_host/src/metrics/mod.rs @@ -93,8 +93,8 @@ mod tests { let recorder = metrics_util::debugging::DebuggingRecorder::new(); let snapshotter = recorder.snapshotter(); let snapshot = with_local_recorder(&recorder, || { - let mut multi = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut multi = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let interrupt_handle = multi.interrupt_handle(); diff --git a/src/hyperlight_host/src/sandbox/host_funcs.rs b/src/hyperlight_host/src/sandbox/host_funcs.rs index c6704c078d..a5b9a645da 100644 --- a/src/hyperlight_host/src/sandbox/host_funcs.rs +++ b/src/hyperlight_host/src/sandbox/host_funcs.rs @@ -85,10 +85,10 @@ impl Default for HostFunctions { /// `HostPrint` function (writes UTF-8 strings to the host's /// stdout in green). /// - /// This matches the default registry installed by - /// `SandboxBuilder::new()`, so a snapshot taken from a + /// This matches the default registry installed by the + /// `SandboxBuilder` constructors, so a snapshot taken from a /// regular sandbox can be loaded with - /// `SandboxBuilder::new().build_from_snapshot(snap)` + /// `SandboxBuilder::from_snapshot(snap).build()` /// without registering anything else. /// /// Use [`HostFunctions::empty`] for an empty registry. diff --git a/src/hyperlight_host/src/sandbox/initialized_multi_use.rs b/src/hyperlight_host/src/sandbox/initialized_multi_use.rs index 8613546dc1..843d446dfc 100644 --- a/src/hyperlight_host/src/sandbox/initialized_multi_use.rs +++ b/src/hyperlight_host/src/sandbox/initialized_multi_use.rs @@ -190,7 +190,7 @@ impl MultiUseSandbox { /// # use hyperlight_host::{HostFunctions, MultiUseSandbox, SandboxBuilder}; /// # fn example() -> Result<(), Box> { /// // Create and initialize a sandbox the normal way - /// let mut sandbox = SandboxBuilder::new().build_from_file("guest.bin")?; + /// let mut sandbox = SandboxBuilder::from_guest_file("guest.bin").build()?; /// /// // Capture a snapshot of the initialized state /// let snapshot = sandbox.snapshot()?; @@ -353,7 +353,7 @@ impl MultiUseSandbox { /// ```no_run /// # use hyperlight_host::SandboxBuilder; /// # fn example() -> Result<(), Box> { - /// let mut sandbox = SandboxBuilder::new().build_from_file("guest.bin")?; + /// let mut sandbox = SandboxBuilder::from_guest_file("guest.bin").build()?; /// /// // Modify sandbox state /// sandbox.call_guest_function_by_name::("SetValue", 42)?; @@ -484,7 +484,7 @@ impl MultiUseSandbox { /// ```no_run /// # use hyperlight_host::SandboxBuilder; /// # fn example() -> Result<(), Box> { - /// let mut sandbox = SandboxBuilder::new().build_from_file("guest.bin")?; + /// let mut sandbox = SandboxBuilder::from_guest_file("guest.bin").build()?; /// /// // Take initial snapshot from this sandbox /// let snapshot = sandbox.snapshot()?; @@ -507,7 +507,7 @@ impl MultiUseSandbox { /// ```no_run /// # use hyperlight_host::SandboxBuilder; /// # fn example() -> Result<(), Box> { - /// let mut sandbox = SandboxBuilder::new().build_from_file("guest.bin")?; + /// let mut sandbox = SandboxBuilder::from_guest_file("guest.bin").build()?; /// /// // Take snapshot before potentially poisoning operation /// let snapshot = sandbox.snapshot()?; @@ -637,7 +637,7 @@ impl MultiUseSandbox { /// ```no_run /// # use hyperlight_host::SandboxBuilder; /// # fn example() -> Result<(), Box> { - /// let mut sandbox = SandboxBuilder::new().build_from_file("guest.bin")?; + /// let mut sandbox = SandboxBuilder::from_guest_file("guest.bin").build()?; /// /// // Call function with no arguments /// let result: i32 = sandbox.call_guest_function_by_name("GetCounter", ())?; @@ -699,7 +699,7 @@ impl MultiUseSandbox { /// ```no_run /// # use hyperlight_host::SandboxBuilder; /// # fn example() -> Result<(), Box> { - /// let mut sandbox = SandboxBuilder::new().build_from_file("guest.bin")?; + /// let mut sandbox = SandboxBuilder::from_guest_file("guest.bin").build()?; /// /// // Call function with no arguments /// let result: i32 = sandbox.call("GetCounter", ())?; @@ -724,7 +724,7 @@ impl MultiUseSandbox { /// ```no_run /// # use hyperlight_host::SandboxBuilder; /// # fn example() -> Result<(), Box> { - /// let mut sandbox = SandboxBuilder::new().build_from_file("guest.bin")?; + /// let mut sandbox = SandboxBuilder::from_guest_file("guest.bin").build()?; /// /// // Take snapshot before risky operation /// let snapshot = sandbox.snapshot()?; @@ -972,7 +972,7 @@ impl MultiUseSandbox { /// # use std::thread; /// # use std::time::Duration; /// # fn example() -> Result<(), Box> { - /// let mut sandbox = SandboxBuilder::new().build_from_file("guest.bin")?; + /// let mut sandbox = SandboxBuilder::from_guest_file("guest.bin").build()?; /// /// // Get interrupt handle before starting long-running operation /// let interrupt_handle = sandbox.interrupt_handle(); @@ -1073,7 +1073,7 @@ impl MultiUseSandbox { /// ```no_run /// # use hyperlight_host::SandboxBuilder; /// # fn example() -> Result<(), Box> { - /// let mut sandbox = SandboxBuilder::new().build_from_file("guest.bin")?; + /// let mut sandbox = SandboxBuilder::from_guest_file("guest.bin").build()?; /// /// if sandbox.status().is_poisoned() { /// println!("Sandbox is poisoned"); @@ -1193,8 +1193,8 @@ mod tests { #[test] fn poison() { - let mut sbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let snapshot = sbox.snapshot().unwrap(); @@ -1280,11 +1280,11 @@ mod tests { #[test] fn host_func_error() { let path = simple_guest_as_pathbuf(); - let mut sandbox = SandboxBuilder::new() + let mut sandbox = SandboxBuilder::from_guest_file(path) .host_function("HostError", || -> Result<()> { Err(HyperlightError::Error("hi".to_string())) }) - .build_from_file(path) + .build() .unwrap(); // will exhaust io if leaky @@ -1305,7 +1305,7 @@ mod tests { #[test] fn call_host_func_expect_error() { let path = simple_guest_as_pathbuf(); - let mut sandbox = SandboxBuilder::new().build_from_file(path).unwrap(); + let mut sandbox = SandboxBuilder::from_guest_file(path).build().unwrap(); sandbox .call::<()>("CallHostExpectError", "SomeUnknownHostFunc".to_string()) .unwrap(); @@ -1315,11 +1315,11 @@ mod tests { #[test] fn io_buffer_reset() { let path = simple_guest_as_pathbuf(); - let mut sandbox = SandboxBuilder::new() + let mut sandbox = SandboxBuilder::from_guest_file(path) .input_data_size(4096) .output_data_size(4096) .host_function("HostAdd", |a: i32, b: i32| a + b) - .build_from_file(path) + .build() .unwrap(); // will exhaust io if leaky. Tests both success and error paths @@ -1336,8 +1336,8 @@ mod tests { /// Tests that call_guest_function_by_name restores the state correctly #[test] fn test_call_guest_function_by_name() { - let mut sbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let snapshot = sbox.snapshot().unwrap(); @@ -1366,7 +1366,7 @@ mod tests { // total, and then add some more for the eagerly-copied page // tables on amd64 let scratch_size = { - let defaults = SandboxBuilder::new(); + let defaults = SandboxConfiguration::default(); hyperlight_common::layout::min_scratch_size( defaults.get_input_data_size(), defaults.get_output_data_size(), @@ -1374,20 +1374,20 @@ mod tests { } + 0x10000 + 0x10000; - let mut sbox1 = SandboxBuilder::new() + let mut sbox1 = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) .heap_size(HEAP_SIZE) .scratch_size(scratch_size) - .build_from_file(simple_guest_as_pathbuf()) + .build() .unwrap(); for _ in 0..1000 { sbox1.call::("Echo", "hello".to_string()).unwrap(); } - let mut sbox2 = SandboxBuilder::new() + let mut sbox2 = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) .heap_size(HEAP_SIZE) .scratch_size(scratch_size) - .build_from_file(simple_guest_as_pathbuf()) + .build() .unwrap(); for i in 0..1000 { @@ -1404,8 +1404,8 @@ mod tests { /// and restoring a snapshot from before evolving restores the previous state #[test] fn snapshot_evolve_restore_handles_state_correctly() { - let mut sbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let snapshot = sbox.snapshot().unwrap(); @@ -1422,8 +1422,8 @@ mod tests { #[test] fn test_trigger_exception_on_guest() { - let mut multi_use_sandbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut multi_use_sandbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let res: Result<()> = multi_use_sandbox.call("TriggerException", ()); @@ -1455,7 +1455,7 @@ mod tests { for _ in 0..SANDBOXES_PER_THREAD { let guest_path = simple_guest_as_pathbuf(); - let mut sandbox = SandboxBuilder::new().build_from_file(guest_path).unwrap(); + let mut sandbox = SandboxBuilder::from_guest_file(guest_path).build().unwrap(); let result: i32 = sandbox.call("GetStatic", ()).unwrap(); assert_eq!(result, 0); @@ -1489,8 +1489,8 @@ mod tests { #[test] fn test_mmap() { - let mut sbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let expected = b"hello world"; @@ -1520,8 +1520,8 @@ mod tests { // Makes sure MemoryRegionFlags::READ | MemoryRegionFlags::EXECUTE executable but not writable #[test] fn test_mmap_write_exec() { - let mut sbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); #[cfg(target_arch = "x86_64")] @@ -1597,8 +1597,8 @@ mod tests { #[test] fn snapshot_restore_handles_remapping_correctly() { - let mut sbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); // 1. Take snapshot 1 with no additional regions mapped @@ -1663,8 +1663,8 @@ mod tests { /// target ever mapping the region. #[test] fn snapshot_restore_across_sandboxes_preserves_mapped_region_contents() { - let mut source = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut source = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let map_mem = allocate_guest_memory(); @@ -1686,8 +1686,8 @@ mod tests { let snapshot = source.snapshot().unwrap(); - let mut target = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut target = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); assert_eq!(target.vm.get_mapped_regions().count(), 0); @@ -1711,12 +1711,12 @@ mod tests { #[test] fn snapshot_restore_across_sandboxes() { - let mut sandbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sandbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); - let mut sandbox2 = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sandbox2 = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); sandbox.call::("AddToStatic", 42i32).unwrap(); @@ -2022,14 +2022,14 @@ mod tests { #[test] fn snapshot_restore_rejects_incompatible_layout() { - let mut sandbox = SandboxBuilder::new() + let mut sandbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) .heap_size(0x10_000) - .build_from_file(simple_guest_as_pathbuf()) + .build() .unwrap(); - let mut sandbox2 = SandboxBuilder::new() + let mut sandbox2 = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) .heap_size(0x20_000) - .build_from_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let snapshot = sandbox.snapshot().unwrap(); @@ -2041,14 +2041,14 @@ mod tests { /// rejected `restore` leaves the target usable. #[test] fn snapshot_restore_failure_leaves_target_usable() { - let mut source = SandboxBuilder::new() + let mut source = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) .heap_size(0x10_000) - .build_from_file(simple_guest_as_pathbuf()) + .build() .unwrap(); - let mut target = SandboxBuilder::new() + let mut target = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) .heap_size(0x20_000) - .build_from_file(simple_guest_as_pathbuf()) + .build() .unwrap(); target.call::("AddToStatic", 5i32).unwrap(); @@ -2071,14 +2071,14 @@ mod tests { /// unmaps anything the target had mapped. #[test] fn snapshot_restore_across_sandboxes_target_has_mapped_regions() { - let mut source = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut source = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); source.call::("AddToStatic", 23i32).unwrap(); let snapshot = source.snapshot().unwrap(); - let mut target = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut target = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let map_mem = allocate_guest_memory(); let guest_base = 0x200000000_usize; @@ -2096,8 +2096,8 @@ mod tests { /// GVA. #[test] fn snapshot_restore_across_sandboxes_both_have_different_mapped_regions() { - let mut source = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut source = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let source_mem = allocate_guest_memory(); let source_base = 0x200000000_usize; @@ -2116,8 +2116,8 @@ mod tests { source.call::("AddToStatic", 9i32).unwrap(); let snapshot = source.snapshot().unwrap(); - let mut target = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut target = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let target_mem = allocate_guest_memory(); let target_base = 0x300000000_usize; @@ -2146,14 +2146,14 @@ mod tests { /// Repeated restore of the same snapshot is idempotent. #[test] fn snapshot_restore_across_sandboxes_repeated() { - let mut source = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut source = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); source.call::("AddToStatic", 7i32).unwrap(); let snapshot = source.snapshot().unwrap(); - let mut target = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut target = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); target.restore(snapshot.clone()).unwrap(); @@ -2170,8 +2170,8 @@ mod tests { /// that restore() calls reset_vcpu(). #[test] fn snapshot_restore_resets_debug_registers() { - let mut sandbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sandbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let snapshot = sandbox.snapshot().unwrap(); @@ -2244,8 +2244,8 @@ mod tests { /// leak into the next call. #[test] fn stale_abort_buffer_does_not_leak_across_calls() { - let mut sbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); // Simulate a partial abort @@ -2276,10 +2276,10 @@ mod tests { for (name, heap_size) in test_cases { let path = simple_guest_as_pathbuf(); - let sbox = SandboxBuilder::new() + let sbox = SandboxBuilder::from_guest_file(path) .heap_size(heap_size) .scratch_size(0x100000) - .build_from_file(path) + .build() .unwrap_or_else(|e| panic!("Failed to create {} sandbox: {}", name, e)); drop(sbox); @@ -2290,7 +2290,7 @@ mod tests { #[cfg(feature = "trace_guest")] fn sandbox_for_gva_tests() -> MultiUseSandbox { let path = simple_guest_as_pathbuf(); - SandboxBuilder::new().build_from_file(path).unwrap() + SandboxBuilder::from_guest_file(path).build().unwrap() } /// Helper: read memory at `gva` of length `len` from the guest side via @@ -2404,8 +2404,8 @@ mod tests { let (path, expected_bytes) = create_test_file("hyperlight_test_map_file_cow_basic.bin", expected); - let mut sbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let guest_base: u64 = 0x1_0000_0000; @@ -2440,8 +2440,8 @@ mod tests { let content = &[0xBB; 4096]; let (path, _) = create_test_file("hyperlight_test_map_file_cow_readonly.bin", content); - let mut sbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let guest_base: u64 = 0x1_0000_0000; @@ -2470,8 +2470,8 @@ mod tests { fn test_map_file_cow_poisoned() { let (path, _) = create_test_file("hyperlight_test_map_file_cow_poison.bin", &[0xCC; 4096]); - let mut sbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let snapshot = sbox.snapshot().unwrap(); @@ -2504,12 +2504,12 @@ mod tests { let guest_base: u64 = 0x1_0000_0000; - let mut sbox1 = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox1 = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); - let mut sbox2 = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox2 = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); // Map the same file into both sandboxes @@ -2564,8 +2564,8 @@ mod tests { handles.push(thread::spawn(move || { barrier.wait(); - let mut sbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let guest_base: u64 = 0x1_0000_0000; @@ -2597,8 +2597,8 @@ mod tests { let (path, _) = create_test_file("hyperlight_test_map_file_cow_cleanup.bin", &[0xDD; 4096]); { - let mut sbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); sbox.map_file_cow(&path, 0x1_0000_0000).unwrap(); @@ -2618,8 +2618,8 @@ mod tests { let (path, expected_bytes) = create_test_file("hyperlight_test_map_file_cow_snapshot_remap.bin", expected); - let mut sbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let guest_base: u64 = 0x1_0000_0000; @@ -2680,8 +2680,8 @@ mod tests { let (path, expected_bytes) = create_test_file("hyperlight_test_map_file_cow_snap_restore.bin", expected); - let mut sbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let guest_base: u64 = 0x1_0000_0000; @@ -2886,8 +2886,8 @@ mod tests { #[test] fn map_region_rejects_overlapping_regions() { - let mut sbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let mem1 = allocate_guest_memory(); @@ -2909,8 +2909,8 @@ mod tests { #[test] fn map_region_rejects_partial_overlap() { - let mut sbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); // Use multi-page regions so partial overlap is geometrically possible @@ -2934,8 +2934,8 @@ mod tests { #[test] fn map_region_allows_adjacent_non_overlapping() { - let mut sbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let mem1 = allocate_guest_memory(); @@ -2954,8 +2954,8 @@ mod tests { #[test] fn map_region_rejects_overlap_with_snapshot() { - let mut sbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); // Try to map at BASE_ADDRESS (0x1000) which overlaps the snapshot region @@ -2974,8 +2974,8 @@ mod tests { #[test] fn map_region_rejects_overlap_with_scratch() { - let mut sbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); // The scratch region occupies the top of the GPA space @@ -3037,8 +3037,8 @@ mod tests { #[test] fn kernel_gs_base_does_not_leak_through_swapgs() { - let mut sandbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sandbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let original: u64 = sandbox.call("ReadKernelGsBaseViaSwapgs", ()).unwrap(); @@ -3071,10 +3071,10 @@ mod tests { #[test] fn snapshot_msr_values_survive_full_in_memory_lifecycle() { - let mut source = SandboxBuilder::new() + let mut source = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) .guest_msrs(&[KERNEL_GS_BASE]) .unwrap() - .build_from_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let first = 0x1111; let second = 0x2222; @@ -3102,10 +3102,10 @@ mod tests { first ); - let mut clone = SandboxBuilder::new() + let mut clone = SandboxBuilder::from_snapshot(first_snapshot.clone()) .guest_msrs(&[KERNEL_GS_BASE]) .unwrap() - .build_from_snapshot(first_snapshot.clone()) + .build() .unwrap(); assert_eq!(clone.call::("ReadMSR", KERNEL_GS_BASE).unwrap(), first); @@ -3120,10 +3120,10 @@ mod tests { third ); - let mut second_clone = SandboxBuilder::new() + let mut second_clone = SandboxBuilder::from_snapshot(third_snapshot) .guest_msrs(&[KERNEL_GS_BASE]) .unwrap() - .build_from_snapshot(third_snapshot) + .build() .unwrap(); assert_eq!( second_clone.call::("ReadMSR", KERNEL_GS_BASE).unwrap(), @@ -3140,10 +3140,10 @@ mod tests { fn equivalent_msr_configs_are_order_independent_across_sandboxes() { let source_order = [KERNEL_GS_BASE, SYSENTER_CS]; let target_order = [SYSENTER_CS, KERNEL_GS_BASE]; - let mut source = SandboxBuilder::new() + let mut source = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) .guest_msrs(&source_order) .unwrap() - .build_from_file(simple_guest_as_pathbuf()) + .build() .unwrap(); source .call::<()>("WriteMSR", (KERNEL_GS_BASE, 0x4444u64)) @@ -3158,10 +3158,10 @@ mod tests { assert_eq!(source.call::("ReadMSR", SYSENTER_CS).unwrap(), 0x5555); let snapshot = source.snapshot().unwrap(); - let mut target = SandboxBuilder::new() + let mut target = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) .guest_msrs(&target_order) .unwrap() - .build_from_file(simple_guest_as_pathbuf()) + .build() .unwrap(); target .call::<()>("WriteMSR", (KERNEL_GS_BASE, 0xAAAAu64)) @@ -3181,10 +3181,10 @@ mod tests { ); assert_eq!(target.call::("ReadMSR", SYSENTER_CS).unwrap(), 0x5555); - let mut clone = SandboxBuilder::new() + let mut clone = SandboxBuilder::from_snapshot(snapshot) .guest_msrs(&target_order) .unwrap() - .build_from_snapshot(snapshot) + .build() .unwrap(); assert_eq!( clone.call::("ReadMSR", KERNEL_GS_BASE).unwrap(), @@ -3200,28 +3200,28 @@ mod tests { fn snapshot_restores_into_superset_guest_msrs() { const SYSENTER_ESP: u32 = 0x175; let sentinel: u64 = 0x1234; - let mut source = SandboxBuilder::new() + let mut source = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) .guest_msrs(&[SYSENTER_CS]) .unwrap() - .build_from_file(simple_guest_as_pathbuf()) + .build() .unwrap(); source .call::<()>("WriteMSR", (SYSENTER_CS, sentinel)) .unwrap(); let snapshot = source.snapshot().unwrap(); - let mut clone = SandboxBuilder::new() + let mut clone = SandboxBuilder::from_snapshot(snapshot.clone()) .guest_msrs(&[SYSENTER_CS, SYSENTER_ESP]) .unwrap() - .build_from_snapshot(snapshot.clone()) + .build() .unwrap(); assert_eq!(clone.call::("ReadMSR", SYSENTER_CS).unwrap(), sentinel); let baseline: u64 = clone.call("ReadMSR", SYSENTER_ESP).unwrap(); - let mut target = SandboxBuilder::new() + let mut target = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) .guest_msrs(&[SYSENTER_CS, SYSENTER_ESP]) .unwrap() - .build_from_file(simple_guest_as_pathbuf()) + .build() .unwrap(); target .call::<()>("WriteMSR", (SYSENTER_ESP, baseline ^ 0x55)) @@ -3245,10 +3245,10 @@ mod tests { #[test] fn snapshot_rejects_non_superset_guest_msrs() { const SYSENTER_ESP: u32 = 0x175; - let mut source = SandboxBuilder::new() + let mut source = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) .guest_msrs(&[SYSENTER_CS]) .unwrap() - .build_from_file(simple_guest_as_pathbuf()) + .build() .unwrap(); source .call::<()>("WriteMSR", (SYSENTER_CS, 0x1234u64)) @@ -3259,17 +3259,17 @@ mod tests { // disjoint MSR, both reject because the snapshot's SYSENTER_CS is // neither declared by the destination nor a core MSR. for dest in [&[][..], &[SYSENTER_ESP][..]] { - let err = SandboxBuilder::new() + let err = SandboxBuilder::from_snapshot(snapshot.clone()) .guest_msrs(dest) .unwrap() - .build_from_snapshot(snapshot.clone()) + .build() .expect_err("from_snapshot must reject an unrestorable snapshot MSR"); assert_snapshot_msr_index_invalid(&err); - let mut target = SandboxBuilder::new() + let mut target = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) .guest_msrs(dest) .unwrap() - .build_from_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let err = target .restore(snapshot.clone()) @@ -3293,10 +3293,10 @@ mod tests { ); assert!(snapshot.msrs().is_none()); - let mut sandbox = SandboxBuilder::new() + let mut sandbox = SandboxBuilder::from_snapshot(snapshot.clone()) .guest_msrs(&[KERNEL_GS_BASE]) .unwrap() - .build_from_snapshot(snapshot.clone()) + .build() .unwrap(); let baseline: u64 = sandbox.call("ReadMSR", KERNEL_GS_BASE).unwrap(); sandbox @@ -3322,8 +3322,8 @@ mod tests { const MSR_X2APIC_BASE: u32 = 0x800; const APIC_BASE_DEFAULT: u64 = 0xFEE0_0900; - let mut sandbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sandbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let snapshot = sandbox.snapshot().unwrap(); @@ -3357,8 +3357,8 @@ mod tests { } } - let mut sbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let snapshot = sbox.snapshot().unwrap(); @@ -3388,8 +3388,8 @@ mod tests { #[test] #[cfg(target_arch = "x86_64")] fn nested_virtualization_is_hidden_from_guest() { - let mut sandbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sandbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let features: u32 = sandbox.call("NestedVirtualizationCpuid", ()).unwrap(); @@ -3405,8 +3405,8 @@ mod tests { return; } - let mut sandbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sandbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let snapshot = sandbox.snapshot().unwrap(); @@ -3433,8 +3433,8 @@ mod tests { #[test] #[cfg(target_arch = "x86_64")] fn guest_cannot_enter_vmx_operation() { - let mut sandbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sandbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let result = sandbox.call::<()>("EnableVmxOperation", ()); @@ -3452,8 +3452,8 @@ mod tests { #[test] #[cfg(target_arch = "x86_64")] fn guest_vmlaunch_faults() { - let mut sandbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sandbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let result = sandbox.call::<()>("ExecuteVmlaunch", ()); @@ -3475,8 +3475,8 @@ mod tests { return; } - let mut sandbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sandbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); assert!( @@ -3490,10 +3490,10 @@ mod tests { #[cfg(target_arch = "x86_64")] fn test_allow_non_resettable_msr_fails_creation() { // IA32_PRED_CMD, a write-only command MSR - let err = SandboxBuilder::new() + let err = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) .guest_msrs(&[0x49]) .unwrap() - .build_from_file(simple_guest_as_pathbuf()) + .build() .unwrap_err(); assert_msr_not_declarable(&err, 0x49); @@ -3510,10 +3510,10 @@ mod tests { } // IA32_MISC_ENABLE: host-probeable, not in MSR_TABLE - let err = SandboxBuilder::new() + let err = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) .guest_msrs(&[0x1A0]) .unwrap() - .build_from_file(simple_guest_as_pathbuf()) + .build() .expect_err("an unclassified declared MSR must be rejected at creation"); assert_msr_not_declarable(&err, 0x1A0); @@ -3525,10 +3525,10 @@ mod tests { // Resettable MSRs the guest may write once declared. let msrs: [u32; 4] = [0x174, 0x175, 0x176, 0xC000_0102]; - let mut sbox = SandboxBuilder::new() + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) .guest_msrs(&msrs) .unwrap() - .build_from_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let baseline_snapshot = sbox.snapshot().unwrap(); @@ -3557,10 +3557,10 @@ mod tests { let msr_index: u32 = 0xC000_0102; // IA32_KERNEL_GS_BASE let sentinel: u64 = 0xCAFE_F00D; - let mut sbox = SandboxBuilder::new() + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) .guest_msrs(&[msr_index]) .unwrap() - .build_from_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let baseline = sbox.snapshot().unwrap(); @@ -3594,8 +3594,8 @@ mod tests { } for msr_index in [0x1D9_u32, 0x800] { - let mut sbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let result = sbox.call::<()>("WriteMSR", (msr_index, 0x1u64)); @@ -3622,8 +3622,8 @@ mod tests { const KVM_CUSTOM_MSR_START: u32 = 0x4B56_4D00; const KVM_CUSTOM_MSR_END: u32 = 0x4B56_4DFF; - let mut sandbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sandbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let snapshot = sandbox.snapshot().unwrap(); @@ -3661,8 +3661,8 @@ mod tests { (0xC001_0117, "AMD VM_HSAVE_PA"), ]; - let mut sbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); for &(msr, _name) in cases { @@ -3675,8 +3675,8 @@ mod tests { #[test] #[cfg(target_arch = "x86_64")] fn misc_enable_guest_write_does_not_survive_restore() { - let mut sbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); assert_msr_write_does_not_survive_restore(&mut sbox, 0x1A0, 1u64 << 40); } @@ -3695,8 +3695,8 @@ mod tests { #[cfg(not(kvm))] let is_kvm = false; - let mut sbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let reset_indices: Vec = sbox.vm.reset_set_indices(); @@ -3926,8 +3926,8 @@ mod tests { return; } - let mut sbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let baseline = sbox.snapshot().unwrap(); @@ -4072,8 +4072,8 @@ mod tests { #[test] #[cfg(all(any(mshv3, target_os = "windows"), target_arch = "x86_64"))] fn active_ssp_does_not_leak_across_restore() { - let mut sbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); if !sbox.call::("CetShadowStackSupported", ()).unwrap() { @@ -4110,8 +4110,8 @@ mod tests { return; } - let mut sbox = SandboxBuilder::new() - .build_from_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + .build() .unwrap(); assert!( !sbox.call::("CetShadowStackSupported", ()).unwrap(), @@ -4120,10 +4120,10 @@ mod tests { // With CET hidden the host cannot read or write IA32_S_CET, so // allowing it is rejected at VM creation. - let err = SandboxBuilder::new() + let err = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) .guest_msrs(&[MSR_S_CET]) .unwrap() - .build_from_file(simple_guest_as_pathbuf()) + .build() .expect_err("allowing IA32_S_CET must be rejected when CET is hidden"); assert_msr_not_declarable(&err, MSR_S_CET); } @@ -4142,15 +4142,15 @@ mod tests { fn make_sandbox() -> MultiUseSandbox { let path = simple_guest_as_pathbuf(); - SandboxBuilder::new().build_from_file(path).unwrap() + SandboxBuilder::from_guest_file(path).build().unwrap() } /// Sandbox with an extra `Add(i32, i32) -> i32` host function. fn make_sandbox_with_add() -> MultiUseSandbox { let path = simple_guest_as_pathbuf(); - SandboxBuilder::new() + SandboxBuilder::from_guest_file(path) .host_function("Add", |a: i32, b: i32| a + b) - .build_from_file(path) + .build() .unwrap() } @@ -4166,7 +4166,7 @@ mod tests { let mut sbox = make_sandbox(); sbox.call::("AddToStatic", 11i32).unwrap(); let snapshot = sbox.snapshot().unwrap(); - let mut sbox2 = SandboxBuilder::new().build_from_snapshot(snapshot).unwrap(); + let mut sbox2 = SandboxBuilder::from_snapshot(snapshot).build().unwrap(); assert_eq!(sbox2.call::("GetStatic", ()).unwrap(), 11); let echoed: String = sbox2.call("Echo", "hi".to_string()).unwrap(); assert_eq!(echoed, "hi"); @@ -4178,8 +4178,8 @@ mod tests { let snap = Snapshot::from_env(GuestBinary::FilePath(path), SandboxConfiguration::default()) .unwrap(); - let mut sbox = SandboxBuilder::new() - .build_from_snapshot(Arc::new(snap)) + let mut sbox = SandboxBuilder::from_snapshot(Arc::new(snap)) + .build() .unwrap(); assert_eq!(sbox.call::("GetStatic", ()).unwrap(), 0); } @@ -4193,11 +4193,11 @@ mod tests { sbox.call::("AddToStatic", 3i32).unwrap(); let snapshot = sbox.snapshot().unwrap(); - let mut a = SandboxBuilder::new() - .build_from_snapshot(snapshot.clone()) + let mut a = SandboxBuilder::from_snapshot(snapshot.clone()) + .build() .unwrap(); - let mut b = SandboxBuilder::new() - .build_from_snapshot(snapshot.clone()) + let mut b = SandboxBuilder::from_snapshot(snapshot.clone()) + .build() .unwrap(); assert_eq!(a.call::("GetStatic", ()).unwrap(), 3); assert_eq!(b.call::("GetStatic", ()).unwrap(), 3); @@ -4217,9 +4217,9 @@ mod tests { let mut sbox = make_sandbox_with_add(); sbox.call::("AddToStatic", 5i32).unwrap(); let snap = sbox.snapshot().unwrap(); - let mut sbox2 = SandboxBuilder::new() + let mut sbox2 = SandboxBuilder::from_snapshot(snap) .host_functions(host_funcs_with_matching_add()) - .build_from_snapshot(snap) + .build() .unwrap(); assert_eq!(sbox2.call::("GetStatic", ()).unwrap(), 5); } @@ -4228,8 +4228,8 @@ mod tests { fn rejects_missing_host_function() { let mut sbox = make_sandbox_with_add(); let snap = sbox.snapshot().unwrap(); - let err = SandboxBuilder::new() - .build_from_snapshot(snap) + let err = SandboxBuilder::from_snapshot(snap) + .build() .expect_err("missing `Add` must be rejected"); assert!( matches!( @@ -4273,9 +4273,9 @@ mod tests { let mut sbox_with_add = make_sandbox_with_add(); let snap = sbox_with_add.snapshot().unwrap(); let path = simple_guest_as_pathbuf(); - let mut sbox_wrong_add = SandboxBuilder::new() + let mut sbox_wrong_add = SandboxBuilder::from_guest_file(path) .host_function("Add", |a: String, b: String| format!("{a}{b}")) - .build_from_file(path) + .build() .unwrap(); let err = sbox_wrong_add .restore(snap) @@ -4300,10 +4300,10 @@ mod tests { let snap = source.snapshot().unwrap(); let path = simple_guest_as_pathbuf(); - let mut target = SandboxBuilder::new() + let mut target = SandboxBuilder::from_guest_file(path) .host_function("Add", |a: i32, b: i32| a + b) .host_function("Mul", |a: i32, b: i32| a * b) - .build_from_file(path) + .build() .unwrap(); target.restore(snap).unwrap(); @@ -4317,9 +4317,9 @@ mod tests { let mut hf = HostFunctions::default(); hf.register_host_function("Add", |a: String, b: String| Ok(format!("{a}{b}"))) .unwrap(); - let err = SandboxBuilder::new() + let err = SandboxBuilder::from_snapshot(snap) .host_functions(hf) - .build_from_snapshot(snap) + .build() .expect_err("signature mismatch on `Add` must be rejected"); assert!( matches!( @@ -4342,9 +4342,9 @@ mod tests { let mut hf = host_funcs_with_matching_add(); hf.register_host_function("Mul", |a: i32, b: i32| Ok(a * b)) .unwrap(); - let mut sbox2 = SandboxBuilder::new() + let mut sbox2 = SandboxBuilder::from_snapshot(snap) .host_functions(hf) - .build_from_snapshot(snap) + .build() .unwrap(); assert_eq!(sbox2.call::("GetStatic", ()).unwrap(), 9); } @@ -4357,7 +4357,7 @@ mod tests { sbox.call::("AddToStatic", 4i32).unwrap(); let snap1 = sbox.snapshot().unwrap(); - let mut sbox2 = SandboxBuilder::new().build_from_snapshot(snap1).unwrap(); + let mut sbox2 = SandboxBuilder::from_snapshot(snap1).build().unwrap(); sbox2.call::("AddToStatic", 6i32).unwrap(); let snap2 = sbox2.snapshot().unwrap(); @@ -4367,7 +4367,7 @@ mod tests { sbox2.restore(snap2.clone()).unwrap(); assert_eq!(sbox2.call::("GetStatic", ()).unwrap(), 10); - let mut sbox3 = SandboxBuilder::new().build_from_snapshot(snap2).unwrap(); + let mut sbox3 = SandboxBuilder::from_snapshot(snap2).build().unwrap(); assert_eq!(sbox3.call::("GetStatic", ()).unwrap(), 10); } @@ -4376,17 +4376,17 @@ mod tests { #[test] fn supplied_host_function_is_callable() { let path = simple_guest_as_pathbuf(); - let mut sbox = SandboxBuilder::new() + let mut sbox = SandboxBuilder::from_guest_file(path) .host_function("Echo42", || 1i64) - .build_from_file(path) + .build() .unwrap(); let snap = sbox.snapshot().unwrap(); let mut hf = HostFunctions::default(); hf.register_host_function("Echo42", || Ok(42i64)).unwrap(); - let mut sbox2 = SandboxBuilder::new() + let mut sbox2 = SandboxBuilder::from_snapshot(snap) .host_functions(hf) - .build_from_snapshot(snap) + .build() .unwrap(); let got: i64 = sbox2 @@ -4409,9 +4409,9 @@ mod tests { let mut hf = HostFunctions::default(); hf.register_host_function("Unrelated", |a: i32| Ok(a + 1)) .unwrap(); - let mut sbox = SandboxBuilder::new() + let mut sbox = SandboxBuilder::from_snapshot(Arc::new(snap)) .host_functions(hf) - .build_from_snapshot(Arc::new(snap)) + .build() .unwrap(); assert_eq!(sbox.call::("GetStatic", ()).unwrap(), 0); } @@ -4430,7 +4430,7 @@ mod tests { let gen2 = snap2.snapshot_generation(); assert_eq!(gen2, gen1 + 1); - let mut sbox2 = SandboxBuilder::new().build_from_snapshot(snap2).unwrap(); + let mut sbox2 = SandboxBuilder::from_snapshot(snap2).build().unwrap(); sbox2.call::("AddToStatic", 1i32).unwrap(); let snap3 = sbox2.snapshot().unwrap(); assert_eq!(snap3.snapshot_generation(), gen2 + 1); @@ -4452,8 +4452,8 @@ mod tests { // host function, so building a sandbox from it without // `Echo42` must fail. let snap = sbox.snapshot().unwrap(); - let err = SandboxBuilder::new() - .build_from_snapshot(snap) + let err = SandboxBuilder::from_snapshot(snap) + .build() .expect_err("late-registered `Echo42` must be required by the new snapshot"); let msg = format!("{}", err); assert!(msg.contains("Echo42"), "got: {}", msg); diff --git a/src/hyperlight_host/src/sandbox/snapshot/file/mod.rs b/src/hyperlight_host/src/sandbox/snapshot/file/mod.rs index 678d1d1626..475a1da3a7 100644 --- a/src/hyperlight_host/src/sandbox/snapshot/file/mod.rs +++ b/src/hyperlight_host/src/sandbox/snapshot/file/mod.rs @@ -327,7 +327,7 @@ impl Snapshot { /// # use hyperlight_host::SandboxBuilder; /// # use hyperlight_host::sandbox::snapshot::OciTag; /// # fn example() -> Result<(), Box> { - /// let mut sandbox = SandboxBuilder::new().build_from_file("guest.bin")?; + /// let mut sandbox = SandboxBuilder::from_guest_file("guest.bin").build()?; /// /// // Capture the initialized state and write it to an OCI layout on disk. /// let snapshot = sandbox.snapshot()?; diff --git a/src/hyperlight_host/src/sandbox/snapshot/file_tests.rs b/src/hyperlight_host/src/sandbox/snapshot/file_tests.rs index 7e200a50e4..caee3be8f0 100644 --- a/src/hyperlight_host/src/sandbox/snapshot/file_tests.rs +++ b/src/hyperlight_host/src/sandbox/snapshot/file_tests.rs @@ -19,12 +19,12 @@ use crate::{GuestBinary, HostFunctions, MultiUseSandbox, SandboxBuilder}; fn create_test_sandbox() -> MultiUseSandbox { let path = simple_guest_as_pathbuf(); - SandboxBuilder::new().build_from_file(path).unwrap() + SandboxBuilder::from_guest_file(path).build().unwrap() } fn create_c_test_sandbox() -> MultiUseSandbox { let path = c_simple_guest_as_pathbuf(); - SandboxBuilder::new().build_from_file(path).unwrap() + SandboxBuilder::from_guest_file(path).build().unwrap() } fn random_sequence(sandbox: &mut MultiUseSandbox) -> [i32; 4] { @@ -267,10 +267,10 @@ fn disk_snapshot_restores_declared_msr_value() { const SYSENTER_CS: u32 = 0x174; let sentinel: u64 = 0xDEAD_BEEF; - let mut source = SandboxBuilder::new() + let mut source = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) .guest_msrs(&[SYSENTER_CS]) .unwrap() - .build_from_file(simple_guest_as_pathbuf()) + .build() .unwrap(); source .call::<()>("WriteMSR", (SYSENTER_CS, sentinel)) @@ -282,10 +282,10 @@ fn disk_snapshot_restores_declared_msr_value() { snap.save(&path, &OciTag::new("latest").unwrap()).unwrap(); let loaded = Arc::new(Snapshot::checked_load(&path, OciTag::new("latest").unwrap()).unwrap()); - let mut sbox = SandboxBuilder::new() + let mut sbox = SandboxBuilder::from_snapshot(loaded.clone()) .guest_msrs(&[SYSENTER_CS]) .unwrap() - .build_from_snapshot(loaded.clone()) + .build() .unwrap(); assert_eq!(sbox.call::("ReadMSR", SYSENTER_CS).unwrap(), sentinel); @@ -304,10 +304,10 @@ fn disk_snapshot_restores_into_superset_guest_msrs() { const SYSENTER_ESP: u32 = 0x175; let sentinel: u64 = 0xDEAD_BEEF; - let mut source = SandboxBuilder::new() + let mut source = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) .guest_msrs(&[SYSENTER_CS]) .unwrap() - .build_from_file(simple_guest_as_pathbuf()) + .build() .unwrap(); source .call::<()>("WriteMSR", (SYSENTER_CS, sentinel)) @@ -319,10 +319,10 @@ fn disk_snapshot_restores_into_superset_guest_msrs() { snap.save(&path, &OciTag::new("latest").unwrap()).unwrap(); let loaded = Arc::new(Snapshot::checked_load(&path, OciTag::new("latest").unwrap()).unwrap()); - let mut sbox = SandboxBuilder::new() + let mut sbox = SandboxBuilder::from_snapshot(loaded) .guest_msrs(&[SYSENTER_CS, SYSENTER_ESP]) .unwrap() - .build_from_snapshot(loaded) + .build() .unwrap(); assert_eq!(sbox.call::("ReadMSR", SYSENTER_CS).unwrap(), sentinel); } @@ -337,10 +337,10 @@ fn disk_snapshot_non_superset_guest_msrs_rejected() { const SYSENTER_CS: u32 = 0x174; let sentinel: u64 = 0x1234; - let mut source = SandboxBuilder::new() + let mut source = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) .guest_msrs(&[SYSENTER_CS]) .unwrap() - .build_from_file(simple_guest_as_pathbuf()) + .build() .unwrap(); source .call::<()>("WriteMSR", (SYSENTER_CS, sentinel)) @@ -728,9 +728,9 @@ fn call_snapshot_without_sregs_rejected() { /// custom `Add(i32, i32) -> i32`. fn create_sandbox_with_custom_host_funcs() -> MultiUseSandbox { let path = simple_guest_as_pathbuf(); - SandboxBuilder::new() + SandboxBuilder::from_guest_file(path) .host_function("Add", |a: i32, b: i32| Ok(a + b)) - .build_from_file(path) + .build() .unwrap() } @@ -825,9 +825,9 @@ fn from_snapshot_accepts_extra_host_functions() { #[test] fn from_snapshot_accepts_zero_arg_host_function() { let path = simple_guest_as_pathbuf(); - let mut sbox = SandboxBuilder::new() + let mut sbox = SandboxBuilder::from_guest_file(path) .host_function("Zero", || Ok(7i64)) - .build_from_file(path) + .build() .unwrap(); let snap = sbox.snapshot().unwrap(); @@ -2570,14 +2570,14 @@ fn index_json_too_large_on_write_rejected() { #[test] fn config_blob_too_large_on_write_rejected() { let guest = simple_guest_as_pathbuf(); - let mut builder = SandboxBuilder::new(); + let mut builder = SandboxBuilder::from_guest_file(guest); // Each host function adds its name and signature to the config // JSON. Long names reach the 1 MiB cap with a modest count. let long = "h".repeat(300); for i in 0..3000 { builder = builder.host_function(format!("{long}{i}"), |a: i32, b: i32| Ok(a + b)); } - let mut sbox = builder.build_from_file(guest).unwrap(); + let mut sbox = builder.build().unwrap(); let snap = sbox.snapshot().unwrap(); let dir = tempfile::tempdir().unwrap(); @@ -2768,9 +2768,9 @@ fn round_trip_preserves_stack_top_gva() { #[test] fn round_trip_preserves_non_default_scratch_size() { let custom_scratch: usize = 256 * 1024; - let mut sbox = SandboxBuilder::new() + let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) .scratch_size(custom_scratch) - .build_from_file(simple_guest_as_pathbuf()) + .build() .unwrap(); let snap = sbox.snapshot().unwrap(); let original = snap.layout().get_scratch_size(); @@ -3159,12 +3159,12 @@ fn from_snapshot_silently_ignores_layout_overrides() { let original_heap = snapshot.layout().heap_size(); let original_scratch = snapshot.layout().get_scratch_size(); - let mut sbox2 = SandboxBuilder::new() + let mut sbox2 = SandboxBuilder::from_snapshot(snapshot.clone()) .input_data_size(original_input * 2) .output_data_size(original_output * 2) .heap_size((original_heap as u64) * 2) .scratch_size(original_scratch * 2) - .build_from_snapshot(snapshot.clone()) + .build() .unwrap(); sbox2.call::("GetStatic", ()).unwrap(); @@ -3277,9 +3277,9 @@ fn from_snapshot_honors_guest_core_dump_enabled() { let mut sbox = create_test_sandbox(); let snapshot = sbox.snapshot().unwrap(); - let mut sbox2 = SandboxBuilder::new() + let mut sbox2 = SandboxBuilder::from_snapshot(snapshot) .guest_core_dump(true) - .build_from_snapshot(snapshot) + .build() .unwrap(); let dir = tempfile::tempdir().unwrap(); @@ -3303,9 +3303,9 @@ fn from_snapshot_honors_guest_core_dump_disabled() { let mut sbox = create_test_sandbox(); let snapshot = sbox.snapshot().unwrap(); - let mut sbox2 = SandboxBuilder::new() + let mut sbox2 = SandboxBuilder::from_snapshot(snapshot) .guest_core_dump(false) - .build_from_snapshot(snapshot) + .build() .unwrap(); let dir = tempfile::tempdir().unwrap(); @@ -3333,9 +3333,9 @@ fn round_trip_preserves_non_default_init_data_permissions() { let path = simple_guest_as_pathbuf(); let data: &[u8] = b"perm-pinned-init-data"; - let mut sbox = SandboxBuilder::new() + let mut sbox = SandboxBuilder::from_guest_file(path) .init_data(data, MemoryRegionFlags::READ | MemoryRegionFlags::WRITE) - .build_from_file(path) + .build() .unwrap(); let snap = sbox.snapshot().unwrap(); let expected = snap.layout().init_data_permissions(); diff --git a/src/hyperlight_host/tests/common/mod.rs b/src/hyperlight_host/tests/common/mod.rs index 141e1adb14..e01c80a00e 100644 --- a/src/hyperlight_host/tests/common/mod.rs +++ b/src/hyperlight_host/tests/common/mod.rs @@ -20,14 +20,19 @@ fn c_guest_path() -> PathBuf { // Rust guest helpers // ============================================================================= -/// Builds a Rust guest MultiUseSandbox from `builder`. -pub fn build_rust_sandbox(builder: SandboxBuilder) -> MultiUseSandbox { - builder.build_from_file(rust_guest_path()).unwrap() +/// Builds a Rust guest MultiUseSandbox, applying `configure` to the builder. +pub fn build_rust_sandbox(configure: C) -> MultiUseSandbox +where + C: FnOnce(SandboxBuilder) -> SandboxBuilder, +{ + configure(SandboxBuilder::from_guest_file(rust_guest_path())) + .build() + .unwrap() } /// Creates a new Rust guest MultiUseSandbox. pub fn new_rust_sandbox() -> MultiUseSandbox { - build_rust_sandbox(SandboxBuilder::new()) + build_rust_sandbox(|builder| builder) } /// Runs a test with a Rust guest MultiUseSandbox. @@ -38,21 +43,27 @@ where f(new_rust_sandbox()); } -/// Runs a test with a Rust guest MultiUseSandbox built from `builder`. -pub fn with_rust_sandbox_from(builder: SandboxBuilder, f: F) +/// Runs a test with a Rust guest MultiUseSandbox built with `configure`. +pub fn with_rust_sandbox_from(configure: C, f: F) where + C: FnOnce(SandboxBuilder) -> SandboxBuilder, F: FnOnce(MultiUseSandbox), { - f(build_rust_sandbox(builder)); + f(build_rust_sandbox(configure)); } // ============================================================================= // C guest helpers // ============================================================================= -/// Builds a C guest MultiUseSandbox from `builder`. -pub fn build_c_sandbox(builder: SandboxBuilder) -> MultiUseSandbox { - builder.build_from_file(c_guest_path()).unwrap() +/// Builds a C guest MultiUseSandbox, applying `configure` to the builder. +pub fn build_c_sandbox(configure: C) -> MultiUseSandbox +where + C: FnOnce(SandboxBuilder) -> SandboxBuilder, +{ + configure(SandboxBuilder::from_guest_file(c_guest_path())) + .build() + .unwrap() } /// Runs a test with a C guest MultiUseSandbox. @@ -60,15 +71,16 @@ pub fn with_c_sandbox(f: F) where F: FnOnce(MultiUseSandbox), { - f(build_c_sandbox(SandboxBuilder::new())); + f(build_c_sandbox(|builder| builder)); } -/// Runs a test with a C guest MultiUseSandbox built from `builder`. -pub fn with_c_sandbox_from(builder: SandboxBuilder, f: F) +/// Runs a test with a C guest MultiUseSandbox built with `configure`. +pub fn with_c_sandbox_from(configure: C, f: F) where + C: FnOnce(SandboxBuilder) -> SandboxBuilder, F: FnOnce(MultiUseSandbox), { - f(build_c_sandbox(builder)); + f(build_c_sandbox(configure)); } // ============================================================================= @@ -94,6 +106,6 @@ where F: Fn(MultiUseSandbox), { with_all_guests(|path| { - f(SandboxBuilder::new().build_from_file(path).unwrap()); + f(SandboxBuilder::from_guest_file(path).build().unwrap()); }); } diff --git a/src/hyperlight_host/tests/integration_test.rs b/src/hyperlight_host/tests/integration_test.rs index 165d753fd4..64cd780de2 100644 --- a/src/hyperlight_host/tests/integration_test.rs +++ b/src/hyperlight_host/tests/integration_test.rs @@ -32,7 +32,7 @@ fn interrupt_host_call() { }; with_rust_sandbox_from( - SandboxBuilder::new().host_function("Spin", spin), + |builder| builder.host_function("Spin", spin), |mut sandbox| { let snapshot = sandbox.snapshot().unwrap(); let interrupt_handle = sandbox.interrupt_handle(); @@ -294,12 +294,14 @@ fn interrupt_moved_sandbox() { #[cfg(target_os = "linux")] #[serial(thread_heavy)] fn interrupt_custom_signal_no_and_retry_delay() { - let builder = SandboxBuilder::new() - .interrupt_vcpu_sigrtmin_offset(0) - .unwrap() - .interrupt_retry_delay(Duration::from_secs(1)); + let configure = |builder: SandboxBuilder| { + builder + .interrupt_vcpu_sigrtmin_offset(0) + .unwrap() + .interrupt_retry_delay(Duration::from_secs(1)) + }; - with_rust_sandbox_from(builder, |mut sbox1| { + with_rust_sandbox_from(configure, |mut sbox1| { let snapshot1 = sbox1.snapshot().unwrap(); let interrupt_handle = sbox1.interrupt_handle(); assert!(!interrupt_handle.dropped()); // not yet dropped @@ -332,11 +334,13 @@ fn interrupt_custom_signal_no_and_retry_delay() { #[test] fn interrupt_spamming_host_call() { - let builder = SandboxBuilder::new().host_function("HostFunc1", || { - // do nothing - }); + let configure = |builder: SandboxBuilder| { + builder.host_function("HostFunc1", || { + // do nothing + }) + }; - with_rust_sandbox_from(builder, |mut sbox1| { + with_rust_sandbox_from(configure, |mut sbox1| { let interrupt_handle = sbox1.interrupt_handle(); let barrier = Arc::new(Barrier::new(2)); @@ -526,8 +530,8 @@ fn guest_malloc_abort() { "precondition: size_to_allocate ({size_to_allocate}) must be > heap_size ({heap_size})" ); - let builder = SandboxBuilder::new().heap_size(heap_size); - with_rust_sandbox_from(builder, |mut sbox2| { + let configure = |builder: SandboxBuilder| builder.heap_size(heap_size); + with_rust_sandbox_from(configure, |mut sbox2| { let err = sbox2 .call::( "CallMalloc", // uses the rust allocator to allocate a vector on heap @@ -599,8 +603,8 @@ fn corrupt_output_back_pointer_rejected() { fn guest_panic_no_alloc() { let heap_size = 0x8000; - let builder = SandboxBuilder::new().heap_size(heap_size); - with_rust_sandbox_from(builder, |mut sbox| { + let configure = |builder: SandboxBuilder| builder.heap_size(heap_size); + with_rust_sandbox_from(configure, |mut sbox| { let res = sbox .call::( "ExhaustHeap", // uses the rust allocator to allocate small blocks on the heap until OOM @@ -797,12 +801,14 @@ fn log_test_messages(levelfilter: Option) { for level in filters.iter() { // Only use Rust guest because the C guest has a different signature for LogMessage // (Long vs Int for the level parameter) - let mut builder = SandboxBuilder::new(); - if let Some(levelfilter) = levelfilter { - builder = builder.guest_log_level(levelfilter); - } + let configure = |mut builder: SandboxBuilder| { + if let Some(levelfilter) = levelfilter { + builder = builder.guest_log_level(levelfilter); + } + builder + }; - with_rust_sandbox_from(builder, |mut sbox1| { + with_rust_sandbox_from(configure, |mut sbox1| { let level: u64 = GuestLogFilter::from(*level).into(); let message = format!("Hello from log_message level {}", level as i32); sbox1 @@ -816,8 +822,9 @@ fn log_test_messages(levelfilter: Option) { /// or not #[test] fn test_if_guest_is_able_to_get_bool_return_values_from_host() { - let builder = SandboxBuilder::new().host_function("HostBool", |a: i32, b: i32| a + b > 10); - with_c_sandbox_from(builder, |mut sbox3| { + let configure = + |builder: SandboxBuilder| builder.host_function("HostBool", |a: i32, b: i32| a + b > 10); + with_c_sandbox_from(configure, |mut sbox3| { for i in 1..10 { if i < 6 { let res = sbox3 @@ -838,8 +845,9 @@ fn test_if_guest_is_able_to_get_bool_return_values_from_host() { /// or not #[test] fn test_if_guest_is_able_to_get_float_return_values_from_host() { - let builder = SandboxBuilder::new().host_function("HostAddFloat", |a: f32, b: f32| a + b); - with_c_sandbox_from(builder, |mut sbox3| { + let configure = + |builder: SandboxBuilder| builder.host_function("HostAddFloat", |a: f32, b: f32| a + b); + with_c_sandbox_from(configure, |mut sbox3| { let res = sbox3 .call::("GuestRetrievesFloatValue", (1.34_f32, 1.34_f32)) .unwrap(); @@ -851,8 +859,9 @@ fn test_if_guest_is_able_to_get_float_return_values_from_host() { /// or not #[test] fn test_if_guest_is_able_to_get_double_return_values_from_host() { - let builder = SandboxBuilder::new().host_function("HostAddDouble", |a: f64, b: f64| a + b); - with_c_sandbox_from(builder, |mut sbox3| { + let configure = + |builder: SandboxBuilder| builder.host_function("HostAddDouble", |a: f64, b: f64| a + b); + with_c_sandbox_from(configure, |mut sbox3| { let res = sbox3 .call::("GuestRetrievesDoubleValue", (1.34_f64, 1.34_f64)) .unwrap(); @@ -864,10 +873,12 @@ fn test_if_guest_is_able_to_get_double_return_values_from_host() { /// or not #[test] fn test_if_guest_is_able_to_get_string_return_values_from_host() { - let builder = SandboxBuilder::new().host_function("HostAddStrings", |a: String| { - a + ", string added by Host Function" - }); - with_c_sandbox_from(builder, |mut sbox3| { + let configure = |builder: SandboxBuilder| { + builder.host_function("HostAddStrings", |a: String| { + a + ", string added by Host Function" + }) + }; + with_c_sandbox_from(configure, |mut sbox3| { let res = sbox3 .call::("GuestRetrievesStringValue", ()) .unwrap(); @@ -1363,13 +1374,12 @@ fn interrupt_infinite_loop_stress_test() { let barrier_for_host = barrier.clone(); // Register a host function that waits on the barrier - let mut sandbox = build_rust_sandbox(SandboxBuilder::new().host_function( - "WaitForKill", - move || { + let mut sandbox = build_rust_sandbox(|builder| { + builder.host_function("WaitForKill", move || { barrier_for_host.wait(); Ok(()) - }, - )); + }) + }); // Take a snapshot to restore after each kill let snapshot = sandbox.snapshot().unwrap(); @@ -1446,11 +1456,12 @@ fn interrupt_infinite_moving_loop_stress_test() { let entered_guest_clone = entered_guest.clone(); // Register a host function that waits on the barrier - let sandbox = - build_rust_sandbox(SandboxBuilder::new().host_function("WaitForKill", move || { + let sandbox = build_rust_sandbox(|builder| { + builder.host_function("WaitForKill", move || { entered_guest.store(true, Ordering::Relaxed); Ok(()) - })); + }) + }); // These 2 sandboxes will have the same TID let bait = new_rust_sandbox(); diff --git a/src/hyperlight_host/tests/sandbox_host_tests.rs b/src/hyperlight_host/tests/sandbox_host_tests.rs index ebe943611a..5803f717eb 100644 --- a/src/hyperlight_host/tests/sandbox_host_tests.rs +++ b/src/hyperlight_host/tests/sandbox_host_tests.rs @@ -104,9 +104,9 @@ fn invalid_guest_function_name() { #[test] fn set_static() { with_all_guests(|path| { - let mut sandbox = SandboxBuilder::new() + let mut sandbox = SandboxBuilder::from_guest_file(path) .scratch_size(0x100C000) - .build_from_file(path) + .build() .unwrap(); let fn_name = "SetStatic"; let res = sandbox.call::(fn_name, ()); @@ -148,9 +148,9 @@ fn multiple_parameters() { } with_all_guests(|path| { - let mut sb = SandboxBuilder::new() + let mut sb = SandboxBuilder::from_guest_file(path) .host_print(writer.clone()) - .build_from_file(path) + .build() .unwrap(); test_case!(sb, rx, "PrintTwoArgs", (a, b)); test_case!(sb, rx, "PrintThreeArgs", (a, b, c)); @@ -198,11 +198,11 @@ fn incorrect_parameter_num() { #[test] fn small_scratch_sandbox() { - let a = SandboxBuilder::new() + let a = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) .scratch_size(0x48000) .input_data_size(0x24000) .output_data_size(0x24000) - .build_from_file(simple_guest_as_pathbuf()); + .build(); assert!(matches!( a.unwrap_err(), @@ -237,9 +237,9 @@ fn simple_test_helper() { let message2 = "world"; with_all_guests(|path| { - let mut sandbox = SandboxBuilder::new() + let mut sandbox = SandboxBuilder::from_guest_file(path) .host_print(writer.clone()) - .build_from_file(path) + .build() .unwrap(); let res: i32 = sandbox.call("PrintOutput", message.to_string()).unwrap(); assert_eq!(res, 5); @@ -291,13 +291,13 @@ fn callback_test_helper() { with_all_guests(|path| { // create host function let (tx, rx) = channel(); - let mut init_sandbox = SandboxBuilder::new() + let mut init_sandbox = SandboxBuilder::from_guest_file(path) .host_function("HostMethod1", move |msg: String| { let len = msg.len(); tx.send(msg).unwrap(); Ok(len as i32) }) - .build_from_file(path) + .build() .unwrap(); // call guest function that calls host function @@ -336,11 +336,11 @@ fn callback_test_parallel() { fn host_function_error() { with_all_guests(|path| { // create host function - let mut init_sandbox = SandboxBuilder::new() + let mut init_sandbox = SandboxBuilder::from_guest_file(path) .host_function("HostMethod1", |_: String| -> Result { Err(new_error!("Host function error!")) }) - .build_from_file(path) + .build() .unwrap(); // call guest function that calls host function diff --git a/src/hyperlight_host/tests/snapshot_goldens/checks.rs b/src/hyperlight_host/tests/snapshot_goldens/checks.rs index 823f712ef4..06cb014bd4 100644 --- a/src/hyperlight_host/tests/snapshot_goldens/checks.rs +++ b/src/hyperlight_host/tests/snapshot_goldens/checks.rs @@ -48,10 +48,10 @@ impl<'a> GoldenTest<'a> { .map_err(|e| format!("Snapshot::checked_load({}): {e}", self.tag()))?; let mut funcs = HostFunctions::default(); register_host_echo_fns(&mut funcs); - SandboxBuilder::new() + SandboxBuilder::from_snapshot(Arc::new(snap)) .host_functions(funcs) - .build_from_snapshot(Arc::new(snap)) - .map_err(|e| format!("build_from_snapshot({}): {e}", self.tag())) + .build() + .map_err(|e| format!("build({}): {e}", self.tag())) } } @@ -297,10 +297,10 @@ fn chained_snapshot(golden: &GoldenTest) -> Result<(), String> { let loaded = Snapshot::checked_load(&layout, tag).map_err(|e| format!("checked_load: {e}"))?; let mut funcs = HostFunctions::default(); register_host_echo_fns(&mut funcs); - let mut sbox2 = SandboxBuilder::new() + let mut sbox2 = SandboxBuilder::from_snapshot(Arc::new(loaded)) .host_functions(funcs) - .build_from_snapshot(Arc::new(loaded)) - .map_err(|e| format!("build_from_snapshot: {e}"))?; + .build() + .map_err(|e| format!("build: {e}"))?; let val: i32 = sbox2 .call("GetStatic", ()) .map_err(|e| format!("GetStatic on chained: {e}"))?; diff --git a/src/hyperlight_host/tests/snapshot_goldens/fixtures.rs b/src/hyperlight_host/tests/snapshot_goldens/fixtures.rs index 252e373d4a..1245684fb2 100644 --- a/src/hyperlight_host/tests/snapshot_goldens/fixtures.rs +++ b/src/hyperlight_host/tests/snapshot_goldens/fixtures.rs @@ -26,7 +26,7 @@ pub(crate) const CALL_COUNTER_BUMP: i32 = 42; /// silent arithmetic change in `SandboxMemoryLayout::new` shifts at /// least one region between generate-time and load-time. fn golden_builder() -> SandboxBuilder { - SandboxBuilder::new() + SandboxBuilder::from_guest_file(simpleguest_path()) .input_data_size(64 * 1024) .output_data_size(64 * 1024) .heap_size(256 * 1024) @@ -42,7 +42,7 @@ pub(crate) fn generate() -> Arc { register_host_echo_fns(&mut funcs); let mut sbox = golden_builder() .host_functions(funcs) - .build_from_file(simpleguest_path()) + .build() .expect("build golden sandbox"); run_canonical_calls(&mut sbox); sbox.snapshot().expect("snapshot") From f9bd735421c16b5be65ea309b4fc2960f1230006 Mon Sep 17 00:00:00 2001 From: Jorge Prendes Date: Fri, 21 Aug 2026 13:43:58 +0100 Subject: [PATCH 4/8] Drop the constructors that predate the guest source `SandboxBuilder::build` is the only way to build a sandbox, and the `from_*` constructors and `guest_*` setters are the only ways to name its source. So the `build_from_*` methods go, along with `new` and its `Default` impl, which could not name one, and `MultiUseSandbox::builder`, which handed out such a builder. Signed-off-by: Jorge Prendes --- src/hyperlight_host/src/sandbox/builder.rs | 48 ++----------------- .../src/sandbox/initialized_multi_use.rs | 9 ---- 2 files changed, 5 insertions(+), 52 deletions(-) diff --git a/src/hyperlight_host/src/sandbox/builder.rs b/src/hyperlight_host/src/sandbox/builder.rs index cbeafdef06..5a71ff7403 100644 --- a/src/hyperlight_host/src/sandbox/builder.rs +++ b/src/hyperlight_host/src/sandbox/builder.rs @@ -46,9 +46,6 @@ impl Source { /// chain the settings you need, then call [`SandboxBuilder::build`]. Every /// setting has a default, so a builder with no adjustments is valid. /// -/// [`SandboxBuilder::new`] starts a builder with no guest, for when the -/// settings are gathered before the guest is known. -/// /// By default only the `HostPrint` host function is registered, which writes /// guest output to the host's stdout. Replace it with [`Self::host_print`]. /// @@ -112,16 +109,6 @@ impl SandboxBuilder { } } - /// Create a builder with an empty guest binary. - /// - /// Equivalent to `from_guest_bytes([])`. Useful to gather settings before - /// the guest is known. Name the source with [`Self::guest_file`], - /// [`Self::guest_bytes`] or [`Self::guest_snapshot`], otherwise - /// [`Self::build`] fails to parse the empty binary. - pub fn new() -> Self { - Self::from_guest_bytes([]) - } - /// Build a sandbox running the guest binary at `path`. pub fn from_guest_file(path: impl AsRef) -> Self { Self::with_source(Source::guest_file(path)) @@ -210,32 +197,6 @@ impl SandboxBuilder { Ok(sandbox) } - - /// Build a sandbox running the guest binary at `path`. - pub fn build_from_file(self, path: impl AsRef) -> Result { - self.guest_file(path).build() - } - - /// Build a sandbox running the guest binary held in `buffer`. - pub fn build_from_bytes(self, buffer: impl Into>) -> Result { - self.guest_bytes(buffer).build() - } - - /// Build a sandbox restored from `snapshot`. - /// - /// # Errors - /// - /// Returns an error if [`Self::init_data`] or [`Self::guest_log_level`] - /// are set. The snapshot already carries both, so they have no effect here. - pub fn build_from_snapshot(self, snapshot: Arc) -> Result { - self.guest_snapshot(snapshot).build() - } -} - -impl Default for SandboxBuilder { - fn default() -> Self { - Self::new() - } } impl SandboxBuilder { @@ -519,11 +480,12 @@ mod tests { } #[test] - fn build_from_new_needs_a_guest() { - assert!(SandboxBuilder::new().build().is_err()); - + fn guest_file_replaces_the_source() { let path = simple_guest_as_string().unwrap(); - let mut sandbox = SandboxBuilder::new().guest_file(path).build().unwrap(); + let mut sandbox = SandboxBuilder::from_guest_bytes([]) + .guest_file(path) + .build() + .unwrap(); let result = sandbox.call::("Echo", "hello".to_string()).unwrap(); assert_eq!(result, "hello"); diff --git a/src/hyperlight_host/src/sandbox/initialized_multi_use.rs b/src/hyperlight_host/src/sandbox/initialized_multi_use.rs index 843d446dfc..85ac5a7a7d 100644 --- a/src/hyperlight_host/src/sandbox/initialized_multi_use.rs +++ b/src/hyperlight_host/src/sandbox/initialized_multi_use.rs @@ -27,7 +27,6 @@ use crate::mem::shared_mem::{HostSharedMemory, SharedMemory as _}; use crate::metrics::{ METRIC_GUEST_ERROR, METRIC_GUEST_ERROR_LABEL_CODE, maybe_time_and_emit_guest_call, }; -use crate::sandbox::builder::SandboxBuilder; use crate::{HyperlightError, Result, log_then_return}; /// The lifecycle state of a [`MultiUseSandbox`]. @@ -107,14 +106,6 @@ pub struct MultiUseSandbox { pub type PtRootFinder = Box Vec + Send>; impl MultiUseSandbox { - /// Start building a sandbox. - /// - /// Returns a [`SandboxBuilder`] with default settings. Adjust it, then call - /// one of its `build_from_*` methods to get a `MultiUseSandbox`. - pub fn builder() -> SandboxBuilder { - SandboxBuilder::new() - } - fn check_ready(&self) -> Result<()> { match self.status { SandboxStatus::Ready => Ok(()), From fa875c61089a4e1dbd1a94413d261c21d47710d2 Mon Sep 17 00:00:00 2001 From: Jorge Prendes Date: Mon, 24 Aug 2026 15:34:45 +0100 Subject: [PATCH 5/8] fixup! Let GuestBinary own its buffer Signed-off-by: Jorge Prendes --- src/hyperlight_host/src/sandbox/uninitialized.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hyperlight_host/src/sandbox/uninitialized.rs b/src/hyperlight_host/src/sandbox/uninitialized.rs index 9caf3bd180..c1bfd10888 100644 --- a/src/hyperlight_host/src/sandbox/uninitialized.rs +++ b/src/hyperlight_host/src/sandbox/uninitialized.rs @@ -127,6 +127,8 @@ impl<'a> From<&'a [u8]> for GuestBlob<'a> { /// /// This struct combines a guest binary (either from a file or memory buffer) with /// optional data that will be available to the guest during execution. +/// +/// The guest binary is owned. `'b` is the lifetime of the borrowed init data. #[derive(Debug)] pub struct GuestEnvironment<'b> { /// The guest binary, which can be a file path or a buffer. From ecc0bc798f670dea1c5dfcb5cd9cba64e8139ce3 Mon Sep 17 00:00:00 2001 From: Jorge Prendes Date: Mon, 24 Aug 2026 15:41:38 +0100 Subject: [PATCH 6/8] fixup! Take the guest source at SandboxBuilder construction Signed-off-by: Jorge Prendes --- src/hyperlight_host/src/sandbox/builder.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hyperlight_host/src/sandbox/builder.rs b/src/hyperlight_host/src/sandbox/builder.rs index 5a71ff7403..ea57ba60e9 100644 --- a/src/hyperlight_host/src/sandbox/builder.rs +++ b/src/hyperlight_host/src/sandbox/builder.rs @@ -224,8 +224,8 @@ impl SandboxBuilder { /// Sets the sandbox `init_data` into the sandbox's memory when it is built, with `flags` as /// the guest's permissions on that region. /// - /// Note: [`Self::build`] errors if this setting is set on a builder created - /// with [`Self::from_snapshot`], as the snapshot already contains the init data. + /// Note: [`Self::build`] errors if this setting is set and the builder's + /// source is a snapshot, as the snapshot already contains the init data. pub fn init_data(mut self, data: impl Into>, flags: MemoryRegionFlags) -> Self { self.init_data = Some((data.into(), flags)); self @@ -263,8 +263,8 @@ impl SandboxBuilder { /// If not set, the log level is determined by the `RUST_LOG` environment variable, /// defaulting to [`LevelFilter::ERROR`] if unset. /// - /// Note: [`Self::build`] errors if this setting is set on a builder created - /// with [`Self::from_snapshot`], as the log level is already captured in the snapshot. + /// Note: [`Self::build`] errors if this setting is set and the builder's + /// source is a snapshot, as the log level is already captured in the snapshot. pub fn guest_log_level(mut self, level: LevelFilter) -> Self { self.guest_log_level = Some(level); self From 9036325f9af2c92b418b5219b0616303069dc6be Mon Sep 17 00:00:00 2001 From: Jorge Prendes Date: Mon, 24 Aug 2026 17:49:20 +0100 Subject: [PATCH 7/8] fixup! Take the guest source at SandboxBuilder construction Signed-off-by: Jorge Prendes --- src/hyperlight_host/src/sandbox/builder.rs | 72 ++++++---------------- 1 file changed, 20 insertions(+), 52 deletions(-) diff --git a/src/hyperlight_host/src/sandbox/builder.rs b/src/hyperlight_host/src/sandbox/builder.rs index ea57ba60e9..7ac5a44126 100644 --- a/src/hyperlight_host/src/sandbox/builder.rs +++ b/src/hyperlight_host/src/sandbox/builder.rs @@ -30,19 +30,19 @@ enum Source { } impl Source { - fn guest_file(path: impl AsRef) -> Self { + fn file(path: impl AsRef) -> Self { Self::GuestBinary(GuestBinary::FilePath(path.as_ref().to_path_buf())) } - fn guest_bytes(buffer: impl Into>) -> Self { + fn bytes(buffer: impl Into>) -> Self { Self::GuestBinary(GuestBinary::Buffer(buffer.into())) } } /// Builds a [`Sandbox`]. /// -/// Start from [`SandboxBuilder::from_guest_file`], -/// [`SandboxBuilder::from_guest_bytes`] or [`SandboxBuilder::from_snapshot`], +/// Start from [`SandboxBuilder::from_file`], +/// [`SandboxBuilder::from_bytes`] or [`SandboxBuilder::from_snapshot`], /// chain the settings you need, then call [`SandboxBuilder::build`]. Every /// setting has a default, so a builder with no adjustments is valid. /// @@ -56,7 +56,7 @@ impl Source { /// ```no_run /// # use hyperlight_host::{Result, SandboxBuilder}; /// # fn example() -> Result<()> { -/// let mut sandbox = SandboxBuilder::from_guest_file("guest.bin") +/// let mut sandbox = SandboxBuilder::from_file("guest.bin") /// .heap_size(1024 * 1024) /// .host_function("Add", |a: i32, b: i32| a + b) /// .build()?; @@ -73,7 +73,7 @@ impl Source { /// ```no_run /// # use hyperlight_host::{Result, SandboxBuilder}; /// # fn example() -> Result<()> { -/// let mut sandbox = SandboxBuilder::from_guest_file("guest.bin") +/// let mut sandbox = SandboxBuilder::from_file("guest.bin") /// .host_function("Add", |a: i32, b: i32| a + b) /// .build()?; /// let snapshot = sandbox.snapshot()?; @@ -109,17 +109,18 @@ impl SandboxBuilder { } } - /// Build a sandbox running the guest binary at `path`. - pub fn from_guest_file(path: impl AsRef) -> Self { - Self::with_source(Source::guest_file(path)) + /// Build a sandbox running the guest binary at `path`, an ELF file. + pub fn from_file(path: impl AsRef) -> Self { + Self::with_source(Source::file(path)) } - /// Build a sandbox running the guest binary held in `buffer`. - pub fn from_guest_bytes(buffer: impl Into>) -> Self { - Self::with_source(Source::guest_bytes(buffer)) + /// Build a sandbox running the guest binary held in `buffer`, the contents + /// of an ELF file. + pub fn from_bytes(buffer: impl Into>) -> Self { + Self::with_source(Source::bytes(buffer)) } - /// Build a sandbox restored from `snapshot`. + /// Build a sandbox restoring the guest from `snapshot`. pub fn from_snapshot(snapshot: Arc) -> Self { Self::with_source(Source::Snapshot(snapshot)) } @@ -200,27 +201,6 @@ impl SandboxBuilder { } impl SandboxBuilder { - /// Run the guest binary at `path`, replacing whatever source the builder - /// was created with. - pub fn guest_file(mut self, path: impl AsRef) -> Self { - self.source = Source::guest_file(path); - self - } - - /// Run the guest binary held in `buffer`, replacing whatever source the - /// builder was created with. - pub fn guest_bytes(mut self, buffer: impl Into>) -> Self { - self.source = Source::guest_bytes(buffer); - self - } - - /// Restore from `snapshot`, replacing whatever source the builder was - /// created with. - pub fn guest_snapshot(mut self, snapshot: Arc) -> Self { - self.source = Source::Snapshot(snapshot); - self - } - /// Sets the sandbox `init_data` into the sandbox's memory when it is built, with `flags` as /// the guest's permissions on that region. /// @@ -459,9 +439,9 @@ mod tests { use crate::mem::memory_region::MemoryRegionFlags; #[test] - fn build_from_guest_file() { + fn build_from_file() { let path = simple_guest_as_string().unwrap(); - let mut sandbox = SandboxBuilder::from_guest_file(path) + let mut sandbox = SandboxBuilder::from_file(path) .input_data_size(0x8000) .build() .unwrap(); @@ -471,21 +451,9 @@ mod tests { } #[test] - fn build_from_guest_bytes() { + fn build_from_bytes() { let bytes = std::fs::read(simple_guest_as_string().unwrap()).unwrap(); - let mut sandbox = SandboxBuilder::from_guest_bytes(bytes).build().unwrap(); - - let result = sandbox.call::("Echo", "hello".to_string()).unwrap(); - assert_eq!(result, "hello"); - } - - #[test] - fn guest_file_replaces_the_source() { - let path = simple_guest_as_string().unwrap(); - let mut sandbox = SandboxBuilder::from_guest_bytes([]) - .guest_file(path) - .build() - .unwrap(); + let mut sandbox = SandboxBuilder::from_bytes(bytes).build().unwrap(); let result = sandbox.call::("Echo", "hello".to_string()).unwrap(); assert_eq!(result, "hello"); @@ -494,7 +462,7 @@ mod tests { #[test] fn build_from_snapshot() { let path = simple_guest_as_string().unwrap(); - let mut sandbox = SandboxBuilder::from_guest_file(path).build().unwrap(); + let mut sandbox = SandboxBuilder::from_file(path).build().unwrap(); let snapshot = sandbox.snapshot().unwrap(); let mut restored = SandboxBuilder::from_snapshot(snapshot).build().unwrap(); @@ -508,7 +476,7 @@ mod tests { #[test] fn build_from_snapshot_errors_on_ignored_settings() { let path = simple_guest_as_string().unwrap(); - let mut sandbox = SandboxBuilder::from_guest_file(path).build().unwrap(); + let mut sandbox = SandboxBuilder::from_file(path).build().unwrap(); let snapshot = sandbox.snapshot().unwrap(); assert!( From 933c2c6337fa0698e4fe7095877818787b0eafb4 Mon Sep 17 00:00:00 2001 From: Jorge Prendes Date: Mon, 24 Aug 2026 17:49:20 +0100 Subject: [PATCH 8/8] fixup! Use the SandboxBuilder guest source constructors Signed-off-by: Jorge Prendes --- README.md | 2 +- docs/how-to-debug-a-hyperlight-guest.md | 2 +- fuzz/fuzz_targets/guest_call.rs | 2 +- fuzz/fuzz_targets/guest_trace.rs | 2 +- fuzz/fuzz_targets/host_call.rs | 2 +- fuzz/fuzz_targets/host_print.rs | 2 +- src/hyperlight_host/benches/benchmarks.rs | 6 +- .../examples/crashdump/main.rs | 10 +- src/hyperlight_host/examples/func_ctx/main.rs | 2 +- .../examples/guest-debugging/main.rs | 11 +- .../examples/hello-world/main.rs | 13 +- src/hyperlight_host/examples/logging/main.rs | 5 +- .../examples/map-file-cow-test/main.rs | 11 +- src/hyperlight_host/examples/metrics/main.rs | 4 +- .../examples/tracing-chrome/main.rs | 2 +- .../examples/tracing-otlp/main.rs | 2 +- src/hyperlight_host/examples/tracing/main.rs | 5 +- src/hyperlight_host/src/metrics/mod.rs | 2 +- .../src/sandbox/initialized_multi_use.rs | 174 +++++++++--------- .../src/sandbox/snapshot/file/mod.rs | 2 +- .../src/sandbox/snapshot/file_tests.rs | 20 +- src/hyperlight_host/tests/common/mod.rs | 6 +- .../tests/sandbox_host_tests.rs | 12 +- .../tests/snapshot_goldens/fixtures.rs | 2 +- 24 files changed, 148 insertions(+), 153 deletions(-) diff --git a/README.md b/README.md index 4a1b401e1e..0cab5b2500 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Hyperlight lets you safely run untrusted code inside hypervisor-isolated micro V // Build a sandbox from a guest binary, registering a host function the guest // can call. In a real app that function might query a database, read a config, // or call an external API. By default, guests can only print to the host. -let mut sandbox = SandboxBuilder::from_guest_file(guest_path) +let mut sandbox = SandboxBuilder::from_file(guest_path) .host_function("GetWeekday", || Ok("Monday".to_string())) .build()?; diff --git a/docs/how-to-debug-a-hyperlight-guest.md b/docs/how-to-debug-a-hyperlight-guest.md index 1f1af78f98..52a1c8ba41 100644 --- a/docs/how-to-debug-a-hyperlight-guest.md +++ b/docs/how-to-debug-a-hyperlight-guest.md @@ -222,7 +222,7 @@ The name and location of the dump file will be printed to the console and logged **NOTE**: By enabling the `crashdump` feature, you instruct Hyperlight to create core dump files for all sandboxes when an unhandled crash occurs. To selectively disable this feature for a specific sandbox, call `guest_core_dump(false)` on the `SandboxBuilder`. ```rust - let sandbox = SandboxBuilder::from_guest_file(guest_path) + let sandbox = SandboxBuilder::from_file(guest_path) .guest_core_dump(false) // Disable core dump for this sandbox .build()?; ``` diff --git a/fuzz/fuzz_targets/guest_call.rs b/fuzz/fuzz_targets/guest_call.rs index 64a0c6ffc9..25e270b893 100644 --- a/fuzz/fuzz_targets/guest_call.rs +++ b/fuzz/fuzz_targets/guest_call.rs @@ -15,7 +15,7 @@ static SANDBOX: OnceLock> = OnceLock::new(); // For fuzzing efficiency, we create one Sandbox and reuse it for all fuzzing iterations. fuzz_target!( init: { - let mu_sbox = SandboxBuilder::from_guest_file(simple_guest_for_fuzzing_as_pathbuf()) + let mu_sbox = SandboxBuilder::from_file(simple_guest_for_fuzzing_as_pathbuf()) .build() .unwrap(); SANDBOX.set(Mutex::new(mu_sbox)).unwrap(); diff --git a/fuzz/fuzz_targets/guest_trace.rs b/fuzz/fuzz_targets/guest_trace.rs index 202cb4eb73..9cb05050fb 100644 --- a/fuzz/fuzz_targets/guest_trace.rs +++ b/fuzz/fuzz_targets/guest_trace.rs @@ -54,7 +54,7 @@ impl<'a> Arbitrary<'a> for FuzzInput { fuzz_target!( init: { // In local tests, 256 KiB seemed sufficient for deep recursion - let mu_sbox = SandboxBuilder::from_guest_file(simple_guest_for_fuzzing_as_pathbuf()) + let mu_sbox = SandboxBuilder::from_file(simple_guest_for_fuzzing_as_pathbuf()) .scratch_size(256 * 1024) .build() .unwrap(); diff --git a/fuzz/fuzz_targets/host_call.rs b/fuzz/fuzz_targets/host_call.rs index e390218aec..6dba3ec466 100644 --- a/fuzz/fuzz_targets/host_call.rs +++ b/fuzz/fuzz_targets/host_call.rs @@ -17,7 +17,7 @@ static SANDBOX: OnceLock> = OnceLock::new(); // For fuzzing efficiency, we create one Sandbox and reuse it for all fuzzing iterations. fuzz_target!( init: { - let mu_sbox = SandboxBuilder::from_guest_file(simple_guest_for_fuzzing_as_pathbuf()) + let mu_sbox = SandboxBuilder::from_file(simple_guest_for_fuzzing_as_pathbuf()) .output_data_size(64 * 1024) // 64 KB output buffer .input_data_size(64 * 1024) // 64 KB input buffer .scratch_size(512 * 1024) // large scratch region to contain those buffers, any data copies, etc. diff --git a/fuzz/fuzz_targets/host_print.rs b/fuzz/fuzz_targets/host_print.rs index 10b52f942f..faf389e681 100644 --- a/fuzz/fuzz_targets/host_print.rs +++ b/fuzz/fuzz_targets/host_print.rs @@ -14,7 +14,7 @@ static SANDBOX: OnceLock> = OnceLock::new(); // For fuzzing efficiency, we create one Sandbox and reuse it for all fuzzing iterations. fuzz_target!( init: { - let mu_sbox = SandboxBuilder::from_guest_file(simple_guest_for_fuzzing_as_pathbuf()) + let mu_sbox = SandboxBuilder::from_file(simple_guest_for_fuzzing_as_pathbuf()) .build() .unwrap(); SANDBOX.set(Mutex::new(mu_sbox)).unwrap(); diff --git a/src/hyperlight_host/benches/benchmarks.rs b/src/hyperlight_host/benches/benchmarks.rs index 03c3b85ae5..70df4384ab 100644 --- a/src/hyperlight_host/benches/benchmarks.rs +++ b/src/hyperlight_host/benches/benchmarks.rs @@ -33,7 +33,7 @@ enum SandboxSize { impl SandboxSize { /// Returns a builder for the simple guest, configured for this sandbox size. fn builder(&self) -> SandboxBuilder { - let builder = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()); + let builder = SandboxBuilder::from_file(simple_guest_as_pathbuf()); match self { Self::Default => builder, Self::Small => builder.heap_size(SMALL_HEAP_SIZE), @@ -350,7 +350,7 @@ fn guest_call_benchmark_large_param(c: &mut Criterion) { let large_vec = vec![0u8; SIZE]; let large_string = String::from_utf8(large_vec.clone()).unwrap(); - let mut sandbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sandbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) // 2 * SIZE + 1 MB, to allow 1MB for the rest of the serialized function call .input_data_size(2 * SIZE + (1024 * 1024)) .heap_size(SIZE as u64 * 15) @@ -432,7 +432,7 @@ fn sample_workloads_benchmark(c: &mut Criterion) { let mut group = c.benchmark_group("sample_workloads"); fn bench_24k_in_8k_out(b: &mut criterion::Bencher, guest_path: std::path::PathBuf) { - let mut sandbox = SandboxBuilder::from_guest_file(guest_path) + let mut sandbox = SandboxBuilder::from_file(guest_path) .input_data_size(25 * 1024) .build() .unwrap(); diff --git a/src/hyperlight_host/examples/crashdump/main.rs b/src/hyperlight_host/examples/crashdump/main.rs index a85dde6366..5ff0a895eb 100644 --- a/src/hyperlight_host/examples/crashdump/main.rs +++ b/src/hyperlight_host/examples/crashdump/main.rs @@ -126,7 +126,7 @@ fn main() -> hyperlight_host::Result<()> { /// 4. The crash dump is written automatically (no explicit call needed) #[cfg(all(crashdump, target_os = "linux"))] fn guest_crash_auto_dump(guest_path: &Path) -> hyperlight_host::Result<()> { - let mut sandbox = SandboxBuilder::from_guest_file(guest_path).build()?; + let mut sandbox = SandboxBuilder::from_file(guest_path).build()?; // Map a file as read-only into the guest at a known address. let mapping_file = create_mapping_file(); @@ -186,7 +186,7 @@ fn create_mapping_file() -> std::path::PathBuf { /// fault), the automatic crash dump code in the VM run loop is not reached. /// To get a crash dump in this case, call `generate_crashdump()` explicitly. fn guest_crash_with_on_demand_dump(guest_path: &Path) -> hyperlight_host::Result<()> { - let mut sandbox = SandboxBuilder::from_guest_file(guest_path).build()?; + let mut sandbox = SandboxBuilder::from_file(guest_path).build()?; // This call triggers a ud2 instruction in the guest. The guest's IDT // catches the #UD exception and reports it back to the host as a @@ -224,7 +224,7 @@ fn guest_crash_with_on_demand_dump(guest_path: &Path) -> hyperlight_host::Result fn guest_crash_with_dump_disabled(guest_path: &Path) -> hyperlight_host::Result<()> { println!("Core dump disabled for this sandbox."); - let mut sandbox = SandboxBuilder::from_guest_file(guest_path) + let mut sandbox = SandboxBuilder::from_file(guest_path) .guest_core_dump(false) .build()?; @@ -360,7 +360,7 @@ mod tests { // Create sandbox with default config (crashdump enabled) let guest_path = hyperlight_testing::simple_guest_as_pathbuf(); - let mut sbox = SandboxBuilder::from_guest_file(guest_path).build().unwrap(); + let mut sbox = SandboxBuilder::from_file(guest_path).build().unwrap(); // Map an additional test file into the guest at a known address. // The core dump already includes snapshot and scratch regions @@ -429,7 +429,7 @@ mod tests { /// sandboxes resolve symbols the same way as directly-evolved ones. fn generate_crashdump_from_snapshot(dump_dir: &Path) -> PathBuf { let guest_path = hyperlight_testing::simple_guest_as_pathbuf(); - let mut sbox = SandboxBuilder::from_guest_file(guest_path) + let mut sbox = SandboxBuilder::from_file(guest_path) .guest_core_dump(true) .build() .unwrap(); diff --git a/src/hyperlight_host/examples/func_ctx/main.rs b/src/hyperlight_host/examples/func_ctx/main.rs index a36f62c7c3..65169def9b 100644 --- a/src/hyperlight_host/examples/func_ctx/main.rs +++ b/src/hyperlight_host/examples/func_ctx/main.rs @@ -8,7 +8,7 @@ fn main() { // create a new `MultiUseSandbox` configured to run the `simpleguest.exe` // test guest binary let path = simple_guest_as_pathbuf(); - let mut sbox = SandboxBuilder::from_guest_file(path).build().unwrap(); + let mut sbox = SandboxBuilder::from_file(path).build().unwrap(); // Do several calls against a sandbox running the `simpleguest.exe` binary, // and print their results diff --git a/src/hyperlight_host/examples/guest-debugging/main.rs b/src/hyperlight_host/examples/guest-debugging/main.rs index b7bd2fc1de..47a493a9bc 100644 --- a/src/hyperlight_host/examples/guest-debugging/main.rs +++ b/src/hyperlight_host/examples/guest-debugging/main.rs @@ -8,7 +8,7 @@ use hyperlight_host::sandbox::config::DebugInfo; /// Build a sandbox builder that enables GDB debugging when the `gdb` feature is enabled. fn debuggable_builder() -> SandboxBuilder { - let builder = SandboxBuilder::from_guest_file(hyperlight_testing::simple_guest_as_pathbuf()); + let builder = SandboxBuilder::from_file(hyperlight_testing::simple_guest_as_pathbuf()); #[cfg(gdb)] let builder = builder.guest_debug_info(DebugInfo { port: 8080 }); @@ -30,7 +30,7 @@ fn main() -> hyperlight_host::Result<()> { // Build a sandbox with a guest binary let mut multi_use_sandbox = - SandboxBuilder::from_guest_file(hyperlight_testing::simple_guest_as_pathbuf()) + SandboxBuilder::from_file(hyperlight_testing::simple_guest_as_pathbuf()) .host_function("Sleep5Secs", sleep_5_secs) .build()?; @@ -339,10 +339,9 @@ mod tests { let (out_file_path, cmd_file_path, manifest_dir) = gdb_test_paths("gdb-from-snapshot"); // Build a sandbox the normal way and snapshot it in-memory. - let mut producer = - SandboxBuilder::from_guest_file(hyperlight_testing::simple_guest_as_pathbuf()) - .build() - .unwrap(); + let mut producer = SandboxBuilder::from_file(hyperlight_testing::simple_guest_as_pathbuf()) + .build() + .unwrap(); let snap = producer.snapshot().unwrap(); // Order matters. The gdb stub event loop must enter (i.e. diff --git a/src/hyperlight_host/examples/hello-world/main.rs b/src/hyperlight_host/examples/hello-world/main.rs index 7f5dd181fd..c1e5744c84 100644 --- a/src/hyperlight_host/examples/hello-world/main.rs +++ b/src/hyperlight_host/examples/hello-world/main.rs @@ -7,13 +7,12 @@ use hyperlight_host::SandboxBuilder; fn main() -> hyperlight_host::Result<()> { // Build a sandbox running a guest binary, with a host function registered. // Note: the host function is unused, it's just here for demonstration purposes - let mut sandbox = - SandboxBuilder::from_guest_file(hyperlight_testing::simple_guest_as_pathbuf()) - .host_function("Sleep5Secs", || { - thread::sleep(std::time::Duration::from_secs(5)); - Ok(()) - }) - .build()?; + let mut sandbox = SandboxBuilder::from_file(hyperlight_testing::simple_guest_as_pathbuf()) + .host_function("Sleep5Secs", || { + thread::sleep(std::time::Duration::from_secs(5)); + Ok(()) + }) + .build()?; // Call guest function let message = "Hello, World! I am executing inside of a VM :)\n".to_string(); diff --git a/src/hyperlight_host/examples/logging/main.rs b/src/hyperlight_host/examples/logging/main.rs index bcce27afd2..c6446802b1 100644 --- a/src/hyperlight_host/examples/logging/main.rs +++ b/src/hyperlight_host/examples/logging/main.rs @@ -25,7 +25,7 @@ fn main() -> Result<()> { let path = hyperlight_guest_path.clone(); let res: Result<()> = { // Create a new sandbox. - let mut multiuse_sandbox = SandboxBuilder::from_guest_file(path) + let mut multiuse_sandbox = SandboxBuilder::from_file(path) .host_print(fn_writer) .build()?; @@ -53,8 +53,7 @@ fn main() -> Result<()> { } // Create a new sandbox. - let mut multiuse_sandbox = - SandboxBuilder::from_guest_file(hyperlight_guest_path.clone()).build()?; + let mut multiuse_sandbox = SandboxBuilder::from_file(hyperlight_guest_path.clone()).build()?; let interrupt_handle = multiuse_sandbox.interrupt_handle(); let barrier = Arc::new(Barrier::new(2)); let barrier2 = barrier.clone(); diff --git a/src/hyperlight_host/examples/map-file-cow-test/main.rs b/src/hyperlight_host/examples/map-file-cow-test/main.rs index c9dcaab254..7a7930acb5 100644 --- a/src/hyperlight_host/examples/map-file-cow-test/main.rs +++ b/src/hyperlight_host/examples/map-file-cow-test/main.rs @@ -20,12 +20,11 @@ use std::path::Path; use hyperlight_host::SandboxBuilder; fn run_once(test_file: &Path, label: &str) -> hyperlight_host::Result<()> { - let mut sandbox = - SandboxBuilder::from_guest_file(hyperlight_testing::simple_guest_as_pathbuf()) - .heap_size(4 * 1024 * 1024) - .scratch_size(64 * 1024 * 1024) - .mapped_file_cow(test_file, 0xC000_0000) - .build()?; + let mut sandbox = SandboxBuilder::from_file(hyperlight_testing::simple_guest_as_pathbuf()) + .heap_size(4 * 1024 * 1024) + .scratch_size(64 * 1024 * 1024) + .mapped_file_cow(test_file, 0xC000_0000) + .build()?; eprintln!( "[{label}] sandbox built with a {} byte file mapped", std::fs::metadata(test_file)?.len() diff --git a/src/hyperlight_host/examples/metrics/main.rs b/src/hyperlight_host/examples/metrics/main.rs index 13488a2b72..9b1084576b 100644 --- a/src/hyperlight_host/examples/metrics/main.rs +++ b/src/hyperlight_host/examples/metrics/main.rs @@ -36,7 +36,7 @@ fn do_hyperlight_stuff() { let path = hyperlight_guest_path.clone(); let handle = spawn(move || -> Result<()> { // Create a new sandbox. - let mut multiuse_sandbox = SandboxBuilder::from_guest_file(path) + let mut multiuse_sandbox = SandboxBuilder::from_file(path) .host_print(fn_writer) .build()?; @@ -64,7 +64,7 @@ fn do_hyperlight_stuff() { } // Create a new sandbox. - let mut multiuse_sandbox = SandboxBuilder::from_guest_file(hyperlight_guest_path.clone()) + let mut multiuse_sandbox = SandboxBuilder::from_file(hyperlight_guest_path.clone()) .build() .expect("Failed to build sandbox"); let interrupt_handle = multiuse_sandbox.interrupt_handle(); diff --git a/src/hyperlight_host/examples/tracing-chrome/main.rs b/src/hyperlight_host/examples/tracing-chrome/main.rs index 4fc474bb89..b7842e2959 100644 --- a/src/hyperlight_host/examples/tracing-chrome/main.rs +++ b/src/hyperlight_host/examples/tracing-chrome/main.rs @@ -14,7 +14,7 @@ fn main() -> Result<()> { let simple_guest_path = simple_guest_as_pathbuf(); // Create a new sandbox. - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_path).build()?; + let mut sbox = SandboxBuilder::from_file(simple_guest_path).build()?; // do the function call let current_time = std::time::Instant::now(); diff --git a/src/hyperlight_host/examples/tracing-otlp/main.rs b/src/hyperlight_host/examples/tracing-otlp/main.rs index b3d77c5af7..3b5a7e1d2a 100644 --- a/src/hyperlight_host/examples/tracing-otlp/main.rs +++ b/src/hyperlight_host/examples/tracing-otlp/main.rs @@ -109,7 +109,7 @@ fn run_example(wait_input: bool) -> HyperlightResult<()> { let _entered = span.enter(); // Create a new sandbox. - let mut multiuse_sandbox = SandboxBuilder::from_guest_file(path.clone()) + let mut multiuse_sandbox = SandboxBuilder::from_file(path.clone()) .host_print(fn_writer) .build()?; diff --git a/src/hyperlight_host/examples/tracing/main.rs b/src/hyperlight_host/examples/tracing/main.rs index 55766925ce..941c3ec9d3 100644 --- a/src/hyperlight_host/examples/tracing/main.rs +++ b/src/hyperlight_host/examples/tracing/main.rs @@ -53,7 +53,7 @@ fn run_example() -> Result<()> { let _entered = span.enter(); // Create a new sandbox. - let mut multiuse_sandbox = SandboxBuilder::from_guest_file(path) + let mut multiuse_sandbox = SandboxBuilder::from_file(path) .host_print(fn_writer) .build()?; @@ -80,8 +80,7 @@ fn run_example() -> Result<()> { } // Create a new sandbox. - let mut multiuse_sandbox = - SandboxBuilder::from_guest_file(hyperlight_guest_path.clone()).build()?; + let mut multiuse_sandbox = SandboxBuilder::from_file(hyperlight_guest_path.clone()).build()?; let interrupt_handle = multiuse_sandbox.interrupt_handle(); // Call a function that gets cancelled by the host function 5 times to generate some log entries. diff --git a/src/hyperlight_host/src/metrics/mod.rs b/src/hyperlight_host/src/metrics/mod.rs index fa3e72f79f..5d6924ba37 100644 --- a/src/hyperlight_host/src/metrics/mod.rs +++ b/src/hyperlight_host/src/metrics/mod.rs @@ -93,7 +93,7 @@ mod tests { let recorder = metrics_util::debugging::DebuggingRecorder::new(); let snapshotter = recorder.snapshotter(); let snapshot = with_local_recorder(&recorder, || { - let mut multi = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut multi = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); let interrupt_handle = multi.interrupt_handle(); diff --git a/src/hyperlight_host/src/sandbox/initialized_multi_use.rs b/src/hyperlight_host/src/sandbox/initialized_multi_use.rs index 85ac5a7a7d..a6df3b40e1 100644 --- a/src/hyperlight_host/src/sandbox/initialized_multi_use.rs +++ b/src/hyperlight_host/src/sandbox/initialized_multi_use.rs @@ -181,7 +181,7 @@ impl MultiUseSandbox { /// # use hyperlight_host::{HostFunctions, MultiUseSandbox, SandboxBuilder}; /// # fn example() -> Result<(), Box> { /// // Create and initialize a sandbox the normal way - /// let mut sandbox = SandboxBuilder::from_guest_file("guest.bin").build()?; + /// let mut sandbox = SandboxBuilder::from_file("guest.bin").build()?; /// /// // Capture a snapshot of the initialized state /// let snapshot = sandbox.snapshot()?; @@ -344,7 +344,7 @@ impl MultiUseSandbox { /// ```no_run /// # use hyperlight_host::SandboxBuilder; /// # fn example() -> Result<(), Box> { - /// let mut sandbox = SandboxBuilder::from_guest_file("guest.bin").build()?; + /// let mut sandbox = SandboxBuilder::from_file("guest.bin").build()?; /// /// // Modify sandbox state /// sandbox.call_guest_function_by_name::("SetValue", 42)?; @@ -475,7 +475,7 @@ impl MultiUseSandbox { /// ```no_run /// # use hyperlight_host::SandboxBuilder; /// # fn example() -> Result<(), Box> { - /// let mut sandbox = SandboxBuilder::from_guest_file("guest.bin").build()?; + /// let mut sandbox = SandboxBuilder::from_file("guest.bin").build()?; /// /// // Take initial snapshot from this sandbox /// let snapshot = sandbox.snapshot()?; @@ -498,7 +498,7 @@ impl MultiUseSandbox { /// ```no_run /// # use hyperlight_host::SandboxBuilder; /// # fn example() -> Result<(), Box> { - /// let mut sandbox = SandboxBuilder::from_guest_file("guest.bin").build()?; + /// let mut sandbox = SandboxBuilder::from_file("guest.bin").build()?; /// /// // Take snapshot before potentially poisoning operation /// let snapshot = sandbox.snapshot()?; @@ -628,7 +628,7 @@ impl MultiUseSandbox { /// ```no_run /// # use hyperlight_host::SandboxBuilder; /// # fn example() -> Result<(), Box> { - /// let mut sandbox = SandboxBuilder::from_guest_file("guest.bin").build()?; + /// let mut sandbox = SandboxBuilder::from_file("guest.bin").build()?; /// /// // Call function with no arguments /// let result: i32 = sandbox.call_guest_function_by_name("GetCounter", ())?; @@ -690,7 +690,7 @@ impl MultiUseSandbox { /// ```no_run /// # use hyperlight_host::SandboxBuilder; /// # fn example() -> Result<(), Box> { - /// let mut sandbox = SandboxBuilder::from_guest_file("guest.bin").build()?; + /// let mut sandbox = SandboxBuilder::from_file("guest.bin").build()?; /// /// // Call function with no arguments /// let result: i32 = sandbox.call("GetCounter", ())?; @@ -715,7 +715,7 @@ impl MultiUseSandbox { /// ```no_run /// # use hyperlight_host::SandboxBuilder; /// # fn example() -> Result<(), Box> { - /// let mut sandbox = SandboxBuilder::from_guest_file("guest.bin").build()?; + /// let mut sandbox = SandboxBuilder::from_file("guest.bin").build()?; /// /// // Take snapshot before risky operation /// let snapshot = sandbox.snapshot()?; @@ -963,7 +963,7 @@ impl MultiUseSandbox { /// # use std::thread; /// # use std::time::Duration; /// # fn example() -> Result<(), Box> { - /// let mut sandbox = SandboxBuilder::from_guest_file("guest.bin").build()?; + /// let mut sandbox = SandboxBuilder::from_file("guest.bin").build()?; /// /// // Get interrupt handle before starting long-running operation /// let interrupt_handle = sandbox.interrupt_handle(); @@ -1064,7 +1064,7 @@ impl MultiUseSandbox { /// ```no_run /// # use hyperlight_host::SandboxBuilder; /// # fn example() -> Result<(), Box> { - /// let mut sandbox = SandboxBuilder::from_guest_file("guest.bin").build()?; + /// let mut sandbox = SandboxBuilder::from_file("guest.bin").build()?; /// /// if sandbox.status().is_poisoned() { /// println!("Sandbox is poisoned"); @@ -1184,7 +1184,7 @@ mod tests { #[test] fn poison() { - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); let snapshot = sbox.snapshot().unwrap(); @@ -1271,7 +1271,7 @@ mod tests { #[test] fn host_func_error() { let path = simple_guest_as_pathbuf(); - let mut sandbox = SandboxBuilder::from_guest_file(path) + let mut sandbox = SandboxBuilder::from_file(path) .host_function("HostError", || -> Result<()> { Err(HyperlightError::Error("hi".to_string())) }) @@ -1296,7 +1296,7 @@ mod tests { #[test] fn call_host_func_expect_error() { let path = simple_guest_as_pathbuf(); - let mut sandbox = SandboxBuilder::from_guest_file(path).build().unwrap(); + let mut sandbox = SandboxBuilder::from_file(path).build().unwrap(); sandbox .call::<()>("CallHostExpectError", "SomeUnknownHostFunc".to_string()) .unwrap(); @@ -1306,7 +1306,7 @@ mod tests { #[test] fn io_buffer_reset() { let path = simple_guest_as_pathbuf(); - let mut sandbox = SandboxBuilder::from_guest_file(path) + let mut sandbox = SandboxBuilder::from_file(path) .input_data_size(4096) .output_data_size(4096) .host_function("HostAdd", |a: i32, b: i32| a + b) @@ -1327,7 +1327,7 @@ mod tests { /// Tests that call_guest_function_by_name restores the state correctly #[test] fn test_call_guest_function_by_name() { - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -1365,7 +1365,7 @@ mod tests { } + 0x10000 + 0x10000; - let mut sbox1 = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox1 = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .heap_size(HEAP_SIZE) .scratch_size(scratch_size) .build() @@ -1375,7 +1375,7 @@ mod tests { sbox1.call::("Echo", "hello".to_string()).unwrap(); } - let mut sbox2 = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox2 = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .heap_size(HEAP_SIZE) .scratch_size(scratch_size) .build() @@ -1395,7 +1395,7 @@ mod tests { /// and restoring a snapshot from before evolving restores the previous state #[test] fn snapshot_evolve_restore_handles_state_correctly() { - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -1413,7 +1413,7 @@ mod tests { #[test] fn test_trigger_exception_on_guest() { - let mut multi_use_sandbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut multi_use_sandbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -1446,7 +1446,7 @@ mod tests { for _ in 0..SANDBOXES_PER_THREAD { let guest_path = simple_guest_as_pathbuf(); - let mut sandbox = SandboxBuilder::from_guest_file(guest_path).build().unwrap(); + let mut sandbox = SandboxBuilder::from_file(guest_path).build().unwrap(); let result: i32 = sandbox.call("GetStatic", ()).unwrap(); assert_eq!(result, 0); @@ -1480,7 +1480,7 @@ mod tests { #[test] fn test_mmap() { - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -1511,7 +1511,7 @@ mod tests { // Makes sure MemoryRegionFlags::READ | MemoryRegionFlags::EXECUTE executable but not writable #[test] fn test_mmap_write_exec() { - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -1588,7 +1588,7 @@ mod tests { #[test] fn snapshot_restore_handles_remapping_correctly() { - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -1654,7 +1654,7 @@ mod tests { /// target ever mapping the region. #[test] fn snapshot_restore_across_sandboxes_preserves_mapped_region_contents() { - let mut source = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut source = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -1677,7 +1677,7 @@ mod tests { let snapshot = source.snapshot().unwrap(); - let mut target = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut target = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); assert_eq!(target.vm.get_mapped_regions().count(), 0); @@ -1702,11 +1702,11 @@ mod tests { #[test] fn snapshot_restore_across_sandboxes() { - let mut sandbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sandbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); - let mut sandbox2 = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sandbox2 = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -2013,12 +2013,12 @@ mod tests { #[test] fn snapshot_restore_rejects_incompatible_layout() { - let mut sandbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sandbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .heap_size(0x10_000) .build() .unwrap(); - let mut sandbox2 = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sandbox2 = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .heap_size(0x20_000) .build() .unwrap(); @@ -2032,12 +2032,12 @@ mod tests { /// rejected `restore` leaves the target usable. #[test] fn snapshot_restore_failure_leaves_target_usable() { - let mut source = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut source = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .heap_size(0x10_000) .build() .unwrap(); - let mut target = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut target = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .heap_size(0x20_000) .build() .unwrap(); @@ -2062,13 +2062,13 @@ mod tests { /// unmaps anything the target had mapped. #[test] fn snapshot_restore_across_sandboxes_target_has_mapped_regions() { - let mut source = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut source = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); source.call::("AddToStatic", 23i32).unwrap(); let snapshot = source.snapshot().unwrap(); - let mut target = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut target = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); let map_mem = allocate_guest_memory(); @@ -2087,7 +2087,7 @@ mod tests { /// GVA. #[test] fn snapshot_restore_across_sandboxes_both_have_different_mapped_regions() { - let mut source = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut source = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); let source_mem = allocate_guest_memory(); @@ -2107,7 +2107,7 @@ mod tests { source.call::("AddToStatic", 9i32).unwrap(); let snapshot = source.snapshot().unwrap(); - let mut target = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut target = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); let target_mem = allocate_guest_memory(); @@ -2137,13 +2137,13 @@ mod tests { /// Repeated restore of the same snapshot is idempotent. #[test] fn snapshot_restore_across_sandboxes_repeated() { - let mut source = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut source = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); source.call::("AddToStatic", 7i32).unwrap(); let snapshot = source.snapshot().unwrap(); - let mut target = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut target = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -2161,7 +2161,7 @@ mod tests { /// that restore() calls reset_vcpu(). #[test] fn snapshot_restore_resets_debug_registers() { - let mut sandbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sandbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -2235,7 +2235,7 @@ mod tests { /// leak into the next call. #[test] fn stale_abort_buffer_does_not_leak_across_calls() { - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -2267,7 +2267,7 @@ mod tests { for (name, heap_size) in test_cases { let path = simple_guest_as_pathbuf(); - let sbox = SandboxBuilder::from_guest_file(path) + let sbox = SandboxBuilder::from_file(path) .heap_size(heap_size) .scratch_size(0x100000) .build() @@ -2281,7 +2281,7 @@ mod tests { #[cfg(feature = "trace_guest")] fn sandbox_for_gva_tests() -> MultiUseSandbox { let path = simple_guest_as_pathbuf(); - SandboxBuilder::from_guest_file(path).build().unwrap() + SandboxBuilder::from_file(path).build().unwrap() } /// Helper: read memory at `gva` of length `len` from the guest side via @@ -2395,7 +2395,7 @@ mod tests { let (path, expected_bytes) = create_test_file("hyperlight_test_map_file_cow_basic.bin", expected); - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -2431,7 +2431,7 @@ mod tests { let content = &[0xBB; 4096]; let (path, _) = create_test_file("hyperlight_test_map_file_cow_readonly.bin", content); - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -2461,7 +2461,7 @@ mod tests { fn test_map_file_cow_poisoned() { let (path, _) = create_test_file("hyperlight_test_map_file_cow_poison.bin", &[0xCC; 4096]); - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); let snapshot = sbox.snapshot().unwrap(); @@ -2495,11 +2495,11 @@ mod tests { let guest_base: u64 = 0x1_0000_0000; - let mut sbox1 = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox1 = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); - let mut sbox2 = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox2 = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -2555,7 +2555,7 @@ mod tests { handles.push(thread::spawn(move || { barrier.wait(); - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -2588,7 +2588,7 @@ mod tests { let (path, _) = create_test_file("hyperlight_test_map_file_cow_cleanup.bin", &[0xDD; 4096]); { - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -2609,7 +2609,7 @@ mod tests { let (path, expected_bytes) = create_test_file("hyperlight_test_map_file_cow_snapshot_remap.bin", expected); - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -2671,7 +2671,7 @@ mod tests { let (path, expected_bytes) = create_test_file("hyperlight_test_map_file_cow_snap_restore.bin", expected); - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -2877,7 +2877,7 @@ mod tests { #[test] fn map_region_rejects_overlapping_regions() { - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -2900,7 +2900,7 @@ mod tests { #[test] fn map_region_rejects_partial_overlap() { - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -2925,7 +2925,7 @@ mod tests { #[test] fn map_region_allows_adjacent_non_overlapping() { - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -2945,7 +2945,7 @@ mod tests { #[test] fn map_region_rejects_overlap_with_snapshot() { - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -2965,7 +2965,7 @@ mod tests { #[test] fn map_region_rejects_overlap_with_scratch() { - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -3028,7 +3028,7 @@ mod tests { #[test] fn kernel_gs_base_does_not_leak_through_swapgs() { - let mut sandbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sandbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -3062,7 +3062,7 @@ mod tests { #[test] fn snapshot_msr_values_survive_full_in_memory_lifecycle() { - let mut source = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut source = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .guest_msrs(&[KERNEL_GS_BASE]) .unwrap() .build() @@ -3131,7 +3131,7 @@ mod tests { fn equivalent_msr_configs_are_order_independent_across_sandboxes() { let source_order = [KERNEL_GS_BASE, SYSENTER_CS]; let target_order = [SYSENTER_CS, KERNEL_GS_BASE]; - let mut source = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut source = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .guest_msrs(&source_order) .unwrap() .build() @@ -3149,7 +3149,7 @@ mod tests { assert_eq!(source.call::("ReadMSR", SYSENTER_CS).unwrap(), 0x5555); let snapshot = source.snapshot().unwrap(); - let mut target = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut target = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .guest_msrs(&target_order) .unwrap() .build() @@ -3191,7 +3191,7 @@ mod tests { fn snapshot_restores_into_superset_guest_msrs() { const SYSENTER_ESP: u32 = 0x175; let sentinel: u64 = 0x1234; - let mut source = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut source = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .guest_msrs(&[SYSENTER_CS]) .unwrap() .build() @@ -3209,7 +3209,7 @@ mod tests { assert_eq!(clone.call::("ReadMSR", SYSENTER_CS).unwrap(), sentinel); let baseline: u64 = clone.call("ReadMSR", SYSENTER_ESP).unwrap(); - let mut target = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut target = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .guest_msrs(&[SYSENTER_CS, SYSENTER_ESP]) .unwrap() .build() @@ -3236,7 +3236,7 @@ mod tests { #[test] fn snapshot_rejects_non_superset_guest_msrs() { const SYSENTER_ESP: u32 = 0x175; - let mut source = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut source = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .guest_msrs(&[SYSENTER_CS]) .unwrap() .build() @@ -3257,7 +3257,7 @@ mod tests { .expect_err("from_snapshot must reject an unrestorable snapshot MSR"); assert_snapshot_msr_index_invalid(&err); - let mut target = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut target = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .guest_msrs(dest) .unwrap() .build() @@ -3313,7 +3313,7 @@ mod tests { const MSR_X2APIC_BASE: u32 = 0x800; const APIC_BASE_DEFAULT: u64 = 0xFEE0_0900; - let mut sandbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sandbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); let snapshot = sandbox.snapshot().unwrap(); @@ -3348,7 +3348,7 @@ mod tests { } } - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -3379,7 +3379,7 @@ mod tests { #[test] #[cfg(target_arch = "x86_64")] fn nested_virtualization_is_hidden_from_guest() { - let mut sandbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sandbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -3396,7 +3396,7 @@ mod tests { return; } - let mut sandbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sandbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -3424,7 +3424,7 @@ mod tests { #[test] #[cfg(target_arch = "x86_64")] fn guest_cannot_enter_vmx_operation() { - let mut sandbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sandbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -3443,7 +3443,7 @@ mod tests { #[test] #[cfg(target_arch = "x86_64")] fn guest_vmlaunch_faults() { - let mut sandbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sandbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -3466,7 +3466,7 @@ mod tests { return; } - let mut sandbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sandbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -3481,7 +3481,7 @@ mod tests { #[cfg(target_arch = "x86_64")] fn test_allow_non_resettable_msr_fails_creation() { // IA32_PRED_CMD, a write-only command MSR - let err = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let err = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .guest_msrs(&[0x49]) .unwrap() .build() @@ -3501,7 +3501,7 @@ mod tests { } // IA32_MISC_ENABLE: host-probeable, not in MSR_TABLE - let err = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let err = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .guest_msrs(&[0x1A0]) .unwrap() .build() @@ -3516,7 +3516,7 @@ mod tests { // Resettable MSRs the guest may write once declared. let msrs: [u32; 4] = [0x174, 0x175, 0x176, 0xC000_0102]; - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .guest_msrs(&msrs) .unwrap() .build() @@ -3548,7 +3548,7 @@ mod tests { let msr_index: u32 = 0xC000_0102; // IA32_KERNEL_GS_BASE let sentinel: u64 = 0xCAFE_F00D; - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .guest_msrs(&[msr_index]) .unwrap() .build() @@ -3585,7 +3585,7 @@ mod tests { } for msr_index in [0x1D9_u32, 0x800] { - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -3613,7 +3613,7 @@ mod tests { const KVM_CUSTOM_MSR_START: u32 = 0x4B56_4D00; const KVM_CUSTOM_MSR_END: u32 = 0x4B56_4DFF; - let mut sandbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sandbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); let snapshot = sandbox.snapshot().unwrap(); @@ -3652,7 +3652,7 @@ mod tests { (0xC001_0117, "AMD VM_HSAVE_PA"), ]; - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -3666,7 +3666,7 @@ mod tests { #[test] #[cfg(target_arch = "x86_64")] fn misc_enable_guest_write_does_not_survive_restore() { - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); assert_msr_write_does_not_survive_restore(&mut sbox, 0x1A0, 1u64 << 40); @@ -3686,7 +3686,7 @@ mod tests { #[cfg(not(kvm))] let is_kvm = false; - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -3917,7 +3917,7 @@ mod tests { return; } - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -4063,7 +4063,7 @@ mod tests { #[test] #[cfg(all(any(mshv3, target_os = "windows"), target_arch = "x86_64"))] fn active_ssp_does_not_leak_across_restore() { - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); @@ -4101,7 +4101,7 @@ mod tests { return; } - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .build() .unwrap(); assert!( @@ -4111,7 +4111,7 @@ mod tests { // With CET hidden the host cannot read or write IA32_S_CET, so // allowing it is rejected at VM creation. - let err = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let err = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .guest_msrs(&[MSR_S_CET]) .unwrap() .build() @@ -4133,13 +4133,13 @@ mod tests { fn make_sandbox() -> MultiUseSandbox { let path = simple_guest_as_pathbuf(); - SandboxBuilder::from_guest_file(path).build().unwrap() + SandboxBuilder::from_file(path).build().unwrap() } /// Sandbox with an extra `Add(i32, i32) -> i32` host function. fn make_sandbox_with_add() -> MultiUseSandbox { let path = simple_guest_as_pathbuf(); - SandboxBuilder::from_guest_file(path) + SandboxBuilder::from_file(path) .host_function("Add", |a: i32, b: i32| a + b) .build() .unwrap() @@ -4264,7 +4264,7 @@ mod tests { let mut sbox_with_add = make_sandbox_with_add(); let snap = sbox_with_add.snapshot().unwrap(); let path = simple_guest_as_pathbuf(); - let mut sbox_wrong_add = SandboxBuilder::from_guest_file(path) + let mut sbox_wrong_add = SandboxBuilder::from_file(path) .host_function("Add", |a: String, b: String| format!("{a}{b}")) .build() .unwrap(); @@ -4291,7 +4291,7 @@ mod tests { let snap = source.snapshot().unwrap(); let path = simple_guest_as_pathbuf(); - let mut target = SandboxBuilder::from_guest_file(path) + let mut target = SandboxBuilder::from_file(path) .host_function("Add", |a: i32, b: i32| a + b) .host_function("Mul", |a: i32, b: i32| a * b) .build() @@ -4367,7 +4367,7 @@ mod tests { #[test] fn supplied_host_function_is_callable() { let path = simple_guest_as_pathbuf(); - let mut sbox = SandboxBuilder::from_guest_file(path) + let mut sbox = SandboxBuilder::from_file(path) .host_function("Echo42", || 1i64) .build() .unwrap(); diff --git a/src/hyperlight_host/src/sandbox/snapshot/file/mod.rs b/src/hyperlight_host/src/sandbox/snapshot/file/mod.rs index 475a1da3a7..0331628de5 100644 --- a/src/hyperlight_host/src/sandbox/snapshot/file/mod.rs +++ b/src/hyperlight_host/src/sandbox/snapshot/file/mod.rs @@ -327,7 +327,7 @@ impl Snapshot { /// # use hyperlight_host::SandboxBuilder; /// # use hyperlight_host::sandbox::snapshot::OciTag; /// # fn example() -> Result<(), Box> { - /// let mut sandbox = SandboxBuilder::from_guest_file("guest.bin").build()?; + /// let mut sandbox = SandboxBuilder::from_file("guest.bin").build()?; /// /// // Capture the initialized state and write it to an OCI layout on disk. /// let snapshot = sandbox.snapshot()?; diff --git a/src/hyperlight_host/src/sandbox/snapshot/file_tests.rs b/src/hyperlight_host/src/sandbox/snapshot/file_tests.rs index caee3be8f0..10fae71ece 100644 --- a/src/hyperlight_host/src/sandbox/snapshot/file_tests.rs +++ b/src/hyperlight_host/src/sandbox/snapshot/file_tests.rs @@ -19,12 +19,12 @@ use crate::{GuestBinary, HostFunctions, MultiUseSandbox, SandboxBuilder}; fn create_test_sandbox() -> MultiUseSandbox { let path = simple_guest_as_pathbuf(); - SandboxBuilder::from_guest_file(path).build().unwrap() + SandboxBuilder::from_file(path).build().unwrap() } fn create_c_test_sandbox() -> MultiUseSandbox { let path = c_simple_guest_as_pathbuf(); - SandboxBuilder::from_guest_file(path).build().unwrap() + SandboxBuilder::from_file(path).build().unwrap() } fn random_sequence(sandbox: &mut MultiUseSandbox) -> [i32; 4] { @@ -267,7 +267,7 @@ fn disk_snapshot_restores_declared_msr_value() { const SYSENTER_CS: u32 = 0x174; let sentinel: u64 = 0xDEAD_BEEF; - let mut source = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut source = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .guest_msrs(&[SYSENTER_CS]) .unwrap() .build() @@ -304,7 +304,7 @@ fn disk_snapshot_restores_into_superset_guest_msrs() { const SYSENTER_ESP: u32 = 0x175; let sentinel: u64 = 0xDEAD_BEEF; - let mut source = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut source = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .guest_msrs(&[SYSENTER_CS]) .unwrap() .build() @@ -337,7 +337,7 @@ fn disk_snapshot_non_superset_guest_msrs_rejected() { const SYSENTER_CS: u32 = 0x174; let sentinel: u64 = 0x1234; - let mut source = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut source = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .guest_msrs(&[SYSENTER_CS]) .unwrap() .build() @@ -728,7 +728,7 @@ fn call_snapshot_without_sregs_rejected() { /// custom `Add(i32, i32) -> i32`. fn create_sandbox_with_custom_host_funcs() -> MultiUseSandbox { let path = simple_guest_as_pathbuf(); - SandboxBuilder::from_guest_file(path) + SandboxBuilder::from_file(path) .host_function("Add", |a: i32, b: i32| Ok(a + b)) .build() .unwrap() @@ -825,7 +825,7 @@ fn from_snapshot_accepts_extra_host_functions() { #[test] fn from_snapshot_accepts_zero_arg_host_function() { let path = simple_guest_as_pathbuf(); - let mut sbox = SandboxBuilder::from_guest_file(path) + let mut sbox = SandboxBuilder::from_file(path) .host_function("Zero", || Ok(7i64)) .build() .unwrap(); @@ -2570,7 +2570,7 @@ fn index_json_too_large_on_write_rejected() { #[test] fn config_blob_too_large_on_write_rejected() { let guest = simple_guest_as_pathbuf(); - let mut builder = SandboxBuilder::from_guest_file(guest); + let mut builder = SandboxBuilder::from_file(guest); // Each host function adds its name and signature to the config // JSON. Long names reach the 1 MiB cap with a modest count. let long = "h".repeat(300); @@ -2768,7 +2768,7 @@ fn round_trip_preserves_stack_top_gva() { #[test] fn round_trip_preserves_non_default_scratch_size() { let custom_scratch: usize = 256 * 1024; - let mut sbox = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let mut sbox = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .scratch_size(custom_scratch) .build() .unwrap(); @@ -3333,7 +3333,7 @@ fn round_trip_preserves_non_default_init_data_permissions() { let path = simple_guest_as_pathbuf(); let data: &[u8] = b"perm-pinned-init-data"; - let mut sbox = SandboxBuilder::from_guest_file(path) + let mut sbox = SandboxBuilder::from_file(path) .init_data(data, MemoryRegionFlags::READ | MemoryRegionFlags::WRITE) .build() .unwrap(); diff --git a/src/hyperlight_host/tests/common/mod.rs b/src/hyperlight_host/tests/common/mod.rs index e01c80a00e..3a96a94a92 100644 --- a/src/hyperlight_host/tests/common/mod.rs +++ b/src/hyperlight_host/tests/common/mod.rs @@ -25,7 +25,7 @@ pub fn build_rust_sandbox(configure: C) -> MultiUseSandbox where C: FnOnce(SandboxBuilder) -> SandboxBuilder, { - configure(SandboxBuilder::from_guest_file(rust_guest_path())) + configure(SandboxBuilder::from_file(rust_guest_path())) .build() .unwrap() } @@ -61,7 +61,7 @@ pub fn build_c_sandbox(configure: C) -> MultiUseSandbox where C: FnOnce(SandboxBuilder) -> SandboxBuilder, { - configure(SandboxBuilder::from_guest_file(c_guest_path())) + configure(SandboxBuilder::from_file(c_guest_path())) .build() .unwrap() } @@ -106,6 +106,6 @@ where F: Fn(MultiUseSandbox), { with_all_guests(|path| { - f(SandboxBuilder::from_guest_file(path).build().unwrap()); + f(SandboxBuilder::from_file(path).build().unwrap()); }); } diff --git a/src/hyperlight_host/tests/sandbox_host_tests.rs b/src/hyperlight_host/tests/sandbox_host_tests.rs index 5803f717eb..6bfe2e5dc2 100644 --- a/src/hyperlight_host/tests/sandbox_host_tests.rs +++ b/src/hyperlight_host/tests/sandbox_host_tests.rs @@ -104,7 +104,7 @@ fn invalid_guest_function_name() { #[test] fn set_static() { with_all_guests(|path| { - let mut sandbox = SandboxBuilder::from_guest_file(path) + let mut sandbox = SandboxBuilder::from_file(path) .scratch_size(0x100C000) .build() .unwrap(); @@ -148,7 +148,7 @@ fn multiple_parameters() { } with_all_guests(|path| { - let mut sb = SandboxBuilder::from_guest_file(path) + let mut sb = SandboxBuilder::from_file(path) .host_print(writer.clone()) .build() .unwrap(); @@ -198,7 +198,7 @@ fn incorrect_parameter_num() { #[test] fn small_scratch_sandbox() { - let a = SandboxBuilder::from_guest_file(simple_guest_as_pathbuf()) + let a = SandboxBuilder::from_file(simple_guest_as_pathbuf()) .scratch_size(0x48000) .input_data_size(0x24000) .output_data_size(0x24000) @@ -237,7 +237,7 @@ fn simple_test_helper() { let message2 = "world"; with_all_guests(|path| { - let mut sandbox = SandboxBuilder::from_guest_file(path) + let mut sandbox = SandboxBuilder::from_file(path) .host_print(writer.clone()) .build() .unwrap(); @@ -291,7 +291,7 @@ fn callback_test_helper() { with_all_guests(|path| { // create host function let (tx, rx) = channel(); - let mut init_sandbox = SandboxBuilder::from_guest_file(path) + let mut init_sandbox = SandboxBuilder::from_file(path) .host_function("HostMethod1", move |msg: String| { let len = msg.len(); tx.send(msg).unwrap(); @@ -336,7 +336,7 @@ fn callback_test_parallel() { fn host_function_error() { with_all_guests(|path| { // create host function - let mut init_sandbox = SandboxBuilder::from_guest_file(path) + let mut init_sandbox = SandboxBuilder::from_file(path) .host_function("HostMethod1", |_: String| -> Result { Err(new_error!("Host function error!")) }) diff --git a/src/hyperlight_host/tests/snapshot_goldens/fixtures.rs b/src/hyperlight_host/tests/snapshot_goldens/fixtures.rs index 1245684fb2..fe1606962c 100644 --- a/src/hyperlight_host/tests/snapshot_goldens/fixtures.rs +++ b/src/hyperlight_host/tests/snapshot_goldens/fixtures.rs @@ -26,7 +26,7 @@ pub(crate) const CALL_COUNTER_BUMP: i32 = 42; /// silent arithmetic change in `SandboxMemoryLayout::new` shifts at /// least one region between generate-time and load-time. fn golden_builder() -> SandboxBuilder { - SandboxBuilder::from_guest_file(simpleguest_path()) + SandboxBuilder::from_file(simpleguest_path()) .input_data_size(64 * 1024) .output_data_size(64 * 1024) .heap_size(256 * 1024)