Skip to content

Commit 3c5e857

Browse files
committed
Add trait to abstract over sandboxes in host function registration
This is useful to allow host-side code to work on both core Hyperlight sandboxes and wrapped sandboxes like Hyperlight Wasm. Signed-off-by: Lucy Menon <[email protected]>
1 parent 44e6654 commit 3c5e857

File tree

1 file changed

+81
-56
lines changed

1 file changed

+81
-56
lines changed

src/hyperlight_host/src/func/host_functions.rs

Lines changed: 81 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ limitations under the License.
1818
use std::sync::{Arc, Mutex};
1919

2020
use hyperlight_common::flatbuffer_wrappers::function_types::ParameterValue;
21-
use hyperlight_common::flatbuffer_wrappers::host_function_definition::HostFunctionDefinition;
21+
pub use hyperlight_common::flatbuffer_wrappers::host_function_definition::HostFunctionDefinition;
2222
use paste::paste;
2323
use tracing::{instrument, Span};
2424

@@ -27,6 +27,51 @@ use crate::sandbox::{ExtraAllowedSyscall, UninitializedSandbox};
2727
use crate::HyperlightError::UnexpectedNoOfArguments;
2828
use crate::{log_then_return, new_error, Result};
2929

30+
/// A sandbox on which (primitive) host functions can be registered
31+
///
32+
/// The details of this trait and the structures it uses are unstable
33+
/// and subject to change, but it must be `pub` because it is used by
34+
/// hyperlight-wasm and the component macros.
35+
pub trait Registerable {
36+
/// Register a primitive host function
37+
fn register_host_function(
38+
&mut self,
39+
hfd: &HostFunctionDefinition,
40+
hf: HyperlightFunction,
41+
) -> Result<()>;
42+
/// Register a primitive host function whose worker thread has
43+
/// extra permissive seccomp filters installed
44+
#[cfg(all(feature = "seccomp", target_os = "linux"))]
45+
fn register_host_function_with_syscalls(
46+
&mut self,
47+
hfd: &HostFunctionDefinition,
48+
hf: HyperlightFunction,
49+
eas: Vec<ExtraAllowedSyscall>,
50+
) -> Result<()>;
51+
}
52+
impl Registerable for UninitializedSandbox {
53+
fn register_host_function(
54+
&mut self,
55+
hfd: &HostFunctionDefinition,
56+
hf: HyperlightFunction,
57+
) -> Result<()> {
58+
let mut hfs = self.host_funcs.try_lock()
59+
.map_err(|e| new_error!("Error locking at {}:{}: {}", file!(), line!(), e))?;
60+
(*hfs).register_host_function(self.mgr.as_mut(), hfd, hf)
61+
}
62+
#[cfg(all(feature = "seccomp", target_os = "linux"))]
63+
fn register_host_function_with_syscalls(
64+
&mut self,
65+
hfd: &HostFunctionDefinition,
66+
hf: HyperlightFunction,
67+
eas: Vec<ExtraAllowedSyscall>,
68+
) -> Result<()> {
69+
let mut hfs = self.host_funcs.try_lock()
70+
.map_err(|e| new_error!("Error locking at {}:{}: {}", file!(), line!(), e))?;
71+
(*hfs).register_host_function_with_syscalls(self.mgr.as_mut(), hfd, hf, eas)
72+
}
73+
}
74+
3075
macro_rules! host_function {
3176
// Special case for zero parameters
3277
(0) => {
@@ -36,15 +81,15 @@ macro_rules! host_function {
3681
/// Register the host function with the given name in the sandbox.
3782
fn register(
3883
&self,
39-
sandbox: &mut UninitializedSandbox,
84+
sandbox: &mut dyn Registerable,
4085
name: &str,
4186
) -> Result<()>;
4287

4388
/// Register the host function with the given name in the sandbox, allowing extra syscalls.
4489
#[cfg(all(feature = "seccomp", target_os = "linux"))]
4590
fn register_with_extra_allowed_syscalls(
4691
&self,
47-
sandbox: &mut UninitializedSandbox,
92+
sandbox: &mut dyn Registerable,
4893
name: &str,
4994
extra_allowed_syscalls: Vec<ExtraAllowedSyscall>,
5095
) -> Result<()>;
@@ -60,7 +105,7 @@ macro_rules! host_function {
60105
)]
61106
fn register(
62107
&self,
63-
sandbox: &mut UninitializedSandbox,
108+
sandbox: &mut dyn Registerable,
64109
name: &str,
65110
) -> Result<()> {
66111
register_host_function_0(self.clone(), sandbox, name, None)
@@ -73,7 +118,7 @@ macro_rules! host_function {
73118
)]
74119
fn register_with_extra_allowed_syscalls(
75120
&self,
76-
sandbox: &mut UninitializedSandbox,
121+
sandbox: &mut dyn Registerable,
77122
name: &str,
78123
extra_allowed_syscalls: Vec<ExtraAllowedSyscall>,
79124
) -> Result<()> {
@@ -83,7 +128,7 @@ macro_rules! host_function {
83128

84129
fn register_host_function_0<T, R>(
85130
self_: Arc<Mutex<T>>,
86-
sandbox: &mut UninitializedSandbox,
131+
sandbox: &mut dyn Registerable,
87132
name: &str,
88133
extra_allowed_syscalls: Option<Vec<ExtraAllowedSyscall>>,
89134
) -> Result<()>
@@ -104,32 +149,22 @@ macro_rules! host_function {
104149
// Register with extra allowed syscalls
105150
#[cfg(all(feature = "seccomp", target_os = "linux"))]
106151
{
107-
sandbox
108-
.host_funcs
109-
.try_lock()
110-
.map_err(|e| new_error!("Error locking at {}:{}: {}", file!(), line!(), e))?
111-
.register_host_function_with_syscalls(
112-
sandbox.mgr.as_mut(),
113-
&HostFunctionDefinition::new(name.to_string(), None, R::get_hyperlight_type()),
114-
HyperlightFunction::new(func),
115-
_eas,
116-
)?;
152+
sandbox.register_host_function_with_syscalls(
153+
&HostFunctionDefinition::new(name.to_string(), None, R::get_hyperlight_type()),
154+
HyperlightFunction::new(func),
155+
_eas,
156+
)?;
117157
}
118158
} else {
119159
// Log and return an error
120160
log_then_return!("Extra allowed syscalls are only supported on Linux with seccomp enabled");
121161
}
122162
} else {
123163
// Register without extra allowed syscalls
124-
sandbox
125-
.host_funcs
126-
.try_lock()
127-
.map_err(|e| new_error!("Error locking at {}:{}: {}", file!(), line!(), e))?
128-
.register_host_function(
129-
sandbox.mgr.as_mut(),
130-
&HostFunctionDefinition::new(name.to_string(), None, R::get_hyperlight_type()),
131-
HyperlightFunction::new(func),
132-
)?;
164+
sandbox.register_host_function(
165+
&HostFunctionDefinition::new(name.to_string(), None, R::get_hyperlight_type()),
166+
HyperlightFunction::new(func),
167+
)?;
133168
}
134169

135170
Ok(())
@@ -148,15 +183,15 @@ macro_rules! host_function {
148183
/// Register the host function with the given name in the sandbox.
149184
fn register(
150185
&self,
151-
sandbox: &mut UninitializedSandbox,
186+
sandbox: &mut dyn Registerable,
152187
name: &str,
153188
) -> Result<()>;
154189

155190
/// Register the host function with the given name in the sandbox, allowing extra syscalls.
156191
#[cfg(all(feature = "seccomp", target_os = "linux"))]
157192
fn register_with_extra_allowed_syscalls(
158193
&self,
159-
sandbox: &mut UninitializedSandbox,
194+
sandbox: &mut dyn Registerable,
160195
name: &str,
161196
extra_allowed_syscalls: Vec<ExtraAllowedSyscall>,
162197
) -> Result<()>;
@@ -173,7 +208,7 @@ macro_rules! host_function {
173208
)]
174209
fn register(
175210
&self,
176-
sandbox: &mut UninitializedSandbox,
211+
sandbox: &mut dyn Registerable,
177212
name: &str,
178213
) -> Result<()> {
179214
[<register_host_function_ $N>](self.clone(), sandbox, name, None)
@@ -186,7 +221,7 @@ macro_rules! host_function {
186221
)]
187222
fn register_with_extra_allowed_syscalls(
188223
&self,
189-
sandbox: &mut UninitializedSandbox,
224+
sandbox: &mut dyn Registerable,
190225
name: &str,
191226
extra_allowed_syscalls: Vec<ExtraAllowedSyscall>,
192227
) -> Result<()> {
@@ -196,7 +231,7 @@ macro_rules! host_function {
196231

197232
fn [<register_host_function_ $N>]<'a, T, $($P,)* R>(
198233
self_: Arc<Mutex<T>>,
199-
sandbox: &mut UninitializedSandbox,
234+
sandbox: &mut dyn Registerable,
200235
name: &str,
201236
extra_allowed_syscalls: Option<Vec<ExtraAllowedSyscall>>,
202237
) -> Result<()>
@@ -231,40 +266,30 @@ macro_rules! host_function {
231266
// Register with extra allowed syscalls
232267
#[cfg(all(feature = "seccomp", target_os = "linux"))]
233268
{
234-
sandbox
235-
.host_funcs
236-
.try_lock()
237-
.map_err(|e| new_error!("Error locking at {}:{}: {}", file!(), line!(), e))?
238-
.register_host_function_with_syscalls(
239-
sandbox.mgr.as_mut(),
240-
&HostFunctionDefinition::new(
241-
name.to_string(),
242-
parameter_types,
243-
R::get_hyperlight_type(),
244-
),
269+
sandbox.register_host_function_with_syscalls(
270+
&HostFunctionDefinition::new(
271+
name.to_string(),
272+
parameter_types,
273+
R::get_hyperlight_type(),
274+
),
245275
HyperlightFunction::new(func),
246-
_eas,
247-
)?;
276+
_eas,
277+
)?;
248278
}
249279
} else {
250280
// Log and return an error
251281
log_then_return!("Extra allowed syscalls are only supported on Linux with seccomp enabled");
252282
}
253283
} else {
254284
// Register without extra allowed syscalls
255-
sandbox
256-
.host_funcs
257-
.try_lock()
258-
.map_err(|e| new_error!("Error locking at {}:{}: {}", file!(), line!(), e))?
259-
.register_host_function(
260-
sandbox.mgr.as_mut(),
261-
&HostFunctionDefinition::new(
262-
name.to_string(),
263-
parameter_types,
264-
R::get_hyperlight_type(),
265-
),
266-
HyperlightFunction::new(func),
267-
)?;
285+
sandbox.register_host_function(
286+
&HostFunctionDefinition::new(
287+
name.to_string(),
288+
parameter_types,
289+
R::get_hyperlight_type(),
290+
),
291+
HyperlightFunction::new(func),
292+
)?;
268293
}
269294

270295
Ok(())

0 commit comments

Comments
 (0)