Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<PathBuf>` instead of `Into<String>`. Callers passing a `String` to `GuestBinary::FilePath` must convert it using `.into()`.
* **Breaking:** `GuestBinary::Buffer` owns its bytes as a `Vec<u8>`, 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
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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_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())?;
Expand Down
4 changes: 2 additions & 2 deletions docs/how-to-debug-a-hyperlight-guest.md
Original file line number Diff line number Diff line change
Expand Up @@ -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_file(guest_path)
.guest_core_dump(false) // Disable core dump for this sandbox
.build_from_file(guest_path)?;
.build()?;
```

## Creating a dump on demand
Expand Down
4 changes: 2 additions & 2 deletions fuzz/fuzz_targets/guest_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ static SANDBOX: OnceLock<Mutex<MultiUseSandbox>> = 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_file(simple_guest_for_fuzzing_as_pathbuf())
.build()
.unwrap();
SANDBOX.set(Mutex::new(mu_sbox)).unwrap();
},
Expand Down
4 changes: 2 additions & 2 deletions fuzz/fuzz_targets/guest_trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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_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();
Expand Down
4 changes: 2 additions & 2 deletions fuzz/fuzz_targets/host_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ static SANDBOX: OnceLock<Mutex<MultiUseSandbox>> = 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_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();
},
Expand Down
4 changes: 2 additions & 2 deletions fuzz/fuzz_targets/host_print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ static SANDBOX: OnceLock<Mutex<MultiUseSandbox>> = 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_file(simple_guest_for_fuzzing_as_pathbuf())
.build()
.unwrap();
SANDBOX.set(Mutex::new(mu_sbox)).unwrap();
},
Expand Down
18 changes: 8 additions & 10 deletions src/hyperlight_host/benches/benchmarks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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_file(simple_guest_as_pathbuf());
match self {
Self::Default => builder,
Self::Small => builder.heap_size(SMALL_HEAP_SIZE),
Expand All @@ -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()
}

// ============================================================================
Expand Down Expand Up @@ -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(|| {
Expand Down Expand Up @@ -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_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(
Expand Down Expand Up @@ -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_file(guest_path)
.input_data_size(25 * 1024)
.build_from_file(guest_path)
.build()
.unwrap();

b.iter_with_setup(
Expand Down
18 changes: 9 additions & 9 deletions src/hyperlight_host/examples/crashdump/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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_file(guest_path).build()?;

// Map a file as read-only into the guest at a known address.
let mapping_file = create_mapping_file();
Expand Down Expand Up @@ -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_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
Expand Down Expand Up @@ -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_file(guest_path)
.guest_core_dump(false)
.build_from_file(guest_path)?;
.build()?;

let mapping_file = create_mapping_file();
let guest_base: u64 = 0x200000000;
Expand Down Expand Up @@ -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_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
Expand Down Expand Up @@ -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_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", ());
Expand Down
2 changes: 1 addition & 1 deletion src/hyperlight_host/examples/func_ctx/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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_file(path).build().unwrap();

// Do several calls against a sandbox running the `simpleguest.exe` binary,
// and print their results
Expand Down
19 changes: 10 additions & 9 deletions src/hyperlight_host/examples/guest-debugging/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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_file(hyperlight_testing::simple_guest_as_pathbuf());

#[cfg(gdb)]
let builder = builder.guest_debug_info(DebugInfo { port: 8080 });
Expand All @@ -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_file(hyperlight_testing::simple_guest_as_pathbuf())
.host_function("Sleep5Secs", sleep_5_secs)
.build()?;

// Call guest function
multi_use_sandbox_dbg
Expand Down Expand Up @@ -338,8 +339,8 @@ 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())
let mut producer = SandboxBuilder::from_file(hyperlight_testing::simple_guest_as_pathbuf())
.build()
.unwrap();
let snap = producer.snapshot().unwrap();

Expand All @@ -353,9 +354,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::<i32>(
"PrintOutput",
"Hello from a from_snapshot sandbox\n".to_string(),
Expand Down
4 changes: 2 additions & 2 deletions src/hyperlight_host/examples/hello-world/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +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::new()
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_from_file(hyperlight_testing::simple_guest_as_pathbuf())?;
.build()?;

// Call guest function
let message = "Hello, World! I am executing inside of a VM :)\n".to_string();
Expand Down
7 changes: 3 additions & 4 deletions src/hyperlight_host/examples/logging/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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_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 {
Expand All @@ -53,8 +53,7 @@ fn main() -> Result<()> {
}

// Create a new sandbox.
let mut multiuse_sandbox =
SandboxBuilder::new().build_from_file(hyperlight_guest_path.clone())?;
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();
Expand Down
4 changes: 2 additions & 2 deletions src/hyperlight_host/examples/map-file-cow-test/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +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::new()
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_from_file(hyperlight_testing::simple_guest_as_pathbuf())?;
.build()?;
eprintln!(
"[{label}] sandbox built with a {} byte file mapped",
std::fs::metadata(test_file)?.len()
Expand Down
8 changes: 4 additions & 4 deletions src/hyperlight_host/examples/metrics/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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_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 {
Expand All @@ -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_file(hyperlight_guest_path.clone())
.build()
.expect("Failed to build sandbox");
let interrupt_handle = multiuse_sandbox.interrupt_handle();

Expand Down
2 changes: 1 addition & 1 deletion src/hyperlight_host/examples/tracing-chrome/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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_file(simple_guest_path).build()?;

// do the function call
let current_time = std::time::Instant::now();
Expand Down
4 changes: 2 additions & 2 deletions src/hyperlight_host/examples/tracing-otlp/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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_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 {
Expand Down
7 changes: 3 additions & 4 deletions src/hyperlight_host/examples/tracing/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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_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 {
Expand All @@ -80,8 +80,7 @@ fn run_example() -> Result<()> {
}

// Create a new sandbox.
let mut multiuse_sandbox =
SandboxBuilder::new().build_from_file(hyperlight_guest_path.clone())?;
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.
Expand Down
Loading
Loading