Skip to main content

hyperlight_host/sandbox/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2025 The Hyperlight Authors.
3
4/// Functionality for creating and configuring `Sandbox`es.
5pub mod builder;
6/// Configuration needed to establish a sandbox.
7pub mod config;
8/// Host-side file mapping preparation for `map_file_cow`.
9pub(crate) mod file_mapping;
10/// Functionality for reading, but not modifying host functions
11pub(crate) mod host_funcs;
12/// Functionality for dealing with initialized sandboxes that can
13/// call 0 or more guest functions
14pub mod initialized_multi_use;
15pub(crate) mod outb;
16/// Functionality for creating uninitialized sandboxes, manipulating them,
17/// and converting them to initialized sandboxes.
18pub mod uninitialized;
19/// Functionality for properly converting `UninitializedSandbox`es to
20/// initialized `Sandbox`es.
21pub(crate) mod uninitialized_evolve;
22
23/// Representation of a snapshot of a `Sandbox`.
24pub mod snapshot;
25
26/// Trait used by the macros to paper over the differences between hyperlight and hyperlight-wasm
27mod callable;
28
29/// Module for tracing guest execution
30#[cfg(feature = "trace_guest")]
31pub(crate) mod trace;
32
33/// Trait used by the macros to paper over the differences between hyperlight and hyperlight-wasm
34pub use callable::Callable;
35/// Re-export for `SandboxConfiguration` type
36pub use config::SandboxConfiguration;
37/// Re-export for the `MultiUseSandbox` type
38pub use initialized_multi_use::{MultiUseSandbox, PtRootFinder, SandboxStatus};
39/// Re-export for `GuestBinary` type
40pub use uninitialized::GuestBinary;
41/// Re-export for `UninitializedSandbox` type
42pub use uninitialized::UninitializedSandbox;
43
44#[cfg(test)]
45mod tests {
46    use std::sync::Arc;
47    use std::thread;
48
49    use crossbeam_queue::ArrayQueue;
50    use hyperlight_testing::simple_guest_as_pathbuf;
51
52    use crate::sandbox::uninitialized::GuestBinary;
53    use crate::{MultiUseSandbox, UninitializedSandbox, new_error};
54
55    #[test]
56    fn check_create_and_use_sandbox_on_different_threads() {
57        let unintializedsandbox_queue = Arc::new(ArrayQueue::<UninitializedSandbox>::new(10));
58        let sandbox_queue = Arc::new(ArrayQueue::<MultiUseSandbox>::new(10));
59
60        for i in 0..10 {
61            let simple_guest_path = simple_guest_as_pathbuf();
62            let unintializedsandbox =
63                UninitializedSandbox::new(GuestBinary::FilePath(simple_guest_path), None)
64                    .unwrap_or_else(|_| panic!("Failed to create UninitializedSandbox {}", i));
65
66            unintializedsandbox_queue
67                .push(unintializedsandbox)
68                .unwrap_or_else(|_| panic!("Failed to push UninitializedSandbox {}", i));
69        }
70
71        let thread_handles = (0..10)
72            .map(|i| {
73                let uq = unintializedsandbox_queue.clone();
74                let sq = sandbox_queue.clone();
75                thread::spawn(move || {
76                    let uninitialized_sandbox = uq.pop().unwrap_or_else(|| {
77                        panic!("Failed to pop UninitializedSandbox thread {}", i)
78                    });
79                    let host_funcs = uninitialized_sandbox
80                        .host_funcs
81                        .try_lock()
82                        .map_err(|_| new_error!("Error locking"));
83
84                    assert!(host_funcs.is_ok());
85
86                    host_funcs
87                        .unwrap()
88                        .host_print(format!(
89                            "Printing from UninitializedSandbox on Thread {}\n",
90                            i
91                        ))
92                        .unwrap();
93
94                    let sandbox = uninitialized_sandbox.evolve().unwrap_or_else(|_| {
95                        panic!("Failed to initialize UninitializedSandbox thread {}", i)
96                    });
97
98                    sq.push(sandbox).unwrap_or_else(|_| {
99                        panic!("Failed to push UninitializedSandbox thread {}", i)
100                    })
101                })
102            })
103            .collect::<Vec<_>>();
104
105        for handle in thread_handles {
106            handle.join().unwrap();
107        }
108
109        let thread_handles = (0..10)
110            .map(|i| {
111                let sq = sandbox_queue.clone();
112                thread::spawn(move || {
113                    let sandbox = sq
114                        .pop()
115                        .unwrap_or_else(|| panic!("Failed to pop Sandbox thread {}", i));
116                    let host_funcs = sandbox
117                        .host_funcs
118                        .try_lock()
119                        .map_err(|_| new_error!("Error locking"));
120
121                    assert!(host_funcs.is_ok());
122
123                    host_funcs
124                        .unwrap()
125                        .host_print(format!("Print from Sandbox on Thread {}\n", i))
126                        .unwrap();
127                })
128            })
129            .collect::<Vec<_>>();
130
131        for handle in thread_handles {
132            handle.join().unwrap();
133        }
134    }
135}