hyperlight_host/sandbox/
mod.rs1pub mod config;
19mod host_funcs;
21pub(crate) mod hypervisor;
23pub mod initialized_multi_use;
26pub(crate) mod mem_access;
29pub(crate) mod mem_mgr;
32pub(crate) mod outb;
33pub mod uninitialized;
36pub(crate) mod uninitialized_evolve;
39
40pub use config::SandboxConfiguration;
42pub use initialized_multi_use::MultiUseSandbox;
44use tracing::{instrument, Span};
45pub use uninitialized::GuestBinary;
47pub use uninitialized::UninitializedSandbox;
49
50use self::mem_mgr::MemMgrWrapper;
51use crate::hypervisor::hypervisor_handler::HypervisorHandler;
52#[cfg(target_os = "windows")]
53use crate::hypervisor::windows_hypervisor_platform;
54use crate::mem::shared_mem::HostSharedMemory;
55
56#[instrument(skip_all, parent = Span::current())]
65pub fn is_supported_platform() -> bool {
66 #[cfg(not(target_os = "linux"))]
67 #[cfg(not(target_os = "windows"))]
68 return false;
69
70 true
71}
72
73pub type ExtraAllowedSyscall = i64;
75
76#[instrument(skip_all, parent = Span::current())]
81pub fn is_hypervisor_present() -> bool {
82 hypervisor::get_available_hypervisor().is_some()
83}
84
85pub(crate) trait WrapperGetter {
86 #[allow(dead_code)]
87 fn get_mgr_wrapper(&self) -> &MemMgrWrapper<HostSharedMemory>;
88 fn get_mgr_wrapper_mut(&mut self) -> &mut MemMgrWrapper<HostSharedMemory>;
89 fn get_hv_handler(&self) -> &HypervisorHandler;
90 #[allow(dead_code)]
91 fn get_hv_handler_mut(&mut self) -> &mut HypervisorHandler;
92}
93
94#[cfg(test)]
95mod tests {
96 use std::sync::Arc;
97 use std::thread;
98
99 use crossbeam_queue::ArrayQueue;
100 use hyperlight_testing::simple_guest_as_string;
101
102 use crate::sandbox::uninitialized::GuestBinary;
103 use crate::sandbox_state::sandbox::EvolvableSandbox;
104 use crate::sandbox_state::transition::Noop;
105 use crate::{new_error, MultiUseSandbox, UninitializedSandbox};
106
107 #[test]
108 #[cfg(target_os = "linux")]
110 fn is_hypervisor_present() {
111 use std::path::Path;
112
113 cfg_if::cfg_if! {
114 if #[cfg(all(kvm, mshv))] {
115 assert_eq!(Path::new("/dev/kvm").exists() || Path::new("/dev/mshv").exists(), super::is_hypervisor_present());
116 } else if #[cfg(kvm)] {
117 assert_eq!(Path::new("/dev/kvm").exists(), super::is_hypervisor_present());
118 } else if #[cfg(mshv)] {
119 assert_eq!(Path::new("/dev/mshv").exists(), super::is_hypervisor_present());
120 } else {
121 assert!(!super::is_hypervisor_present());
122 }
123 }
124 }
125
126 #[test]
127 fn check_create_and_use_sandbox_on_different_threads() {
128 let unintializedsandbox_queue = Arc::new(ArrayQueue::<UninitializedSandbox>::new(10));
129 let sandbox_queue = Arc::new(ArrayQueue::<MultiUseSandbox>::new(10));
130
131 for i in 0..10 {
132 let simple_guest_path = simple_guest_as_string().expect("Guest Binary Missing");
133 let unintializedsandbox =
134 UninitializedSandbox::new(GuestBinary::FilePath(simple_guest_path), None)
135 .unwrap_or_else(|_| panic!("Failed to create UninitializedSandbox {}", i));
136
137 unintializedsandbox_queue
138 .push(unintializedsandbox)
139 .unwrap_or_else(|_| panic!("Failed to push UninitializedSandbox {}", i));
140 }
141
142 let thread_handles = (0..10)
143 .map(|i| {
144 let uq = unintializedsandbox_queue.clone();
145 let sq = sandbox_queue.clone();
146 thread::spawn(move || {
147 let uninitialized_sandbox = uq.pop().unwrap_or_else(|| {
148 panic!("Failed to pop UninitializedSandbox thread {}", i)
149 });
150 let host_funcs = uninitialized_sandbox
151 .host_funcs
152 .try_lock()
153 .map_err(|_| new_error!("Error locking"));
154
155 assert!(host_funcs.is_ok());
156
157 host_funcs
158 .unwrap()
159 .host_print(format!(
160 "Printing from UninitializedSandbox on Thread {}\n",
161 i
162 ))
163 .unwrap();
164
165 let sandbox = uninitialized_sandbox
166 .evolve(Noop::default())
167 .unwrap_or_else(|_| {
168 panic!("Failed to initialize UninitializedSandbox thread {}", i)
169 });
170
171 sq.push(sandbox).unwrap_or_else(|_| {
172 panic!("Failed to push UninitializedSandbox thread {}", i)
173 })
174 })
175 })
176 .collect::<Vec<_>>();
177
178 for handle in thread_handles {
179 handle.join().unwrap();
180 }
181
182 let thread_handles = (0..10)
183 .map(|i| {
184 let sq = sandbox_queue.clone();
185 thread::spawn(move || {
186 let sandbox = sq
187 .pop()
188 .unwrap_or_else(|| panic!("Failed to pop Sandbox thread {}", i));
189 let host_funcs = sandbox
190 ._host_funcs
191 .try_lock()
192 .map_err(|_| new_error!("Error locking"));
193
194 assert!(host_funcs.is_ok());
195
196 host_funcs
197 .unwrap()
198 .host_print(format!("Print from Sandbox on Thread {}\n", i))
199 .unwrap();
200 })
201 })
202 .collect::<Vec<_>>();
203
204 for handle in thread_handles {
205 handle.join().unwrap();
206 }
207 }
208}