Skip to content

Commit 16d8a22

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 16d8a22

File tree

1 file changed

+85
-56
lines changed

1 file changed

+85
-56
lines changed

src/hyperlight_host/src/func/host_functions.rs

Lines changed: 85 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,55 @@ 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
59+
.host_funcs
60+
.try_lock()
61+
.map_err(|e| new_error!("Error locking at {}:{}: {}", file!(), line!(), e))?;
62+
(*hfs).register_host_function(self.mgr.as_mut(), hfd, hf)
63+
}
64+
#[cfg(all(feature = "seccomp", target_os = "linux"))]
65+
fn register_host_function_with_syscalls(
66+
&mut self,
67+
hfd: &HostFunctionDefinition,
68+
hf: HyperlightFunction,
69+
eas: Vec<ExtraAllowedSyscall>,
70+
) -> Result<()> {
71+
let mut hfs = self
72+
.host_funcs
73+
.try_lock()
74+
.map_err(|e| new_error!("Error locking at {}:{}: {}", file!(), line!(), e))?;
75+
(*hfs).register_host_function_with_syscalls(self.mgr.as_mut(), hfd, hf, eas)
76+
}
77+
}
78+
3079
macro_rules! host_function {
3180
// Special case for zero parameters
3281
(0) => {
@@ -36,15 +85,15 @@ macro_rules! host_function {
3685
/// Register the host function with the given name in the sandbox.
3786
fn register(
3887
&self,
39-
sandbox: &mut UninitializedSandbox,
88+
sandbox: &mut dyn Registerable,
4089
name: &str,
4190
) -> Result<()>;
4291

4392
/// Register the host function with the given name in the sandbox, allowing extra syscalls.
4493
#[cfg(all(feature = "seccomp", target_os = "linux"))]
4594
fn register_with_extra_allowed_syscalls(
4695
&self,
47-
sandbox: &mut UninitializedSandbox,
96+
sandbox: &mut dyn Registerable,
4897
name: &str,
4998
extra_allowed_syscalls: Vec<ExtraAllowedSyscall>,
5099
) -> Result<()>;
@@ -60,7 +109,7 @@ macro_rules! host_function {
60109
)]
61110
fn register(
62111
&self,
63-
sandbox: &mut UninitializedSandbox,
112+
sandbox: &mut dyn Registerable,
64113
name: &str,
65114
) -> Result<()> {
66115
register_host_function_0(self.clone(), sandbox, name, None)
@@ -73,7 +122,7 @@ macro_rules! host_function {
73122
)]
74123
fn register_with_extra_allowed_syscalls(
75124
&self,
76-
sandbox: &mut UninitializedSandbox,
125+
sandbox: &mut dyn Registerable,
77126
name: &str,
78127
extra_allowed_syscalls: Vec<ExtraAllowedSyscall>,
79128
) -> Result<()> {
@@ -83,7 +132,7 @@ macro_rules! host_function {
83132

84133
fn register_host_function_0<T, R>(
85134
self_: Arc<Mutex<T>>,
86-
sandbox: &mut UninitializedSandbox,
135+
sandbox: &mut dyn Registerable,
87136
name: &str,
88137
extra_allowed_syscalls: Option<Vec<ExtraAllowedSyscall>>,
89138
) -> Result<()>
@@ -104,32 +153,22 @@ macro_rules! host_function {
104153
// Register with extra allowed syscalls
105154
#[cfg(all(feature = "seccomp", target_os = "linux"))]
106155
{
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-
)?;
156+
sandbox.register_host_function_with_syscalls(
157+
&HostFunctionDefinition::new(name.to_string(), None, R::get_hyperlight_type()),
158+
HyperlightFunction::new(func),
159+
_eas,
160+
)?;
117161
}
118162
} else {
119163
// Log and return an error
120164
log_then_return!("Extra allowed syscalls are only supported on Linux with seccomp enabled");
121165
}
122166
} else {
123167
// 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-
)?;
168+
sandbox.register_host_function(
169+
&HostFunctionDefinition::new(name.to_string(), None, R::get_hyperlight_type()),
170+
HyperlightFunction::new(func),
171+
)?;
133172
}
134173

135174
Ok(())
@@ -148,15 +187,15 @@ macro_rules! host_function {
148187
/// Register the host function with the given name in the sandbox.
149188
fn register(
150189
&self,
151-
sandbox: &mut UninitializedSandbox,
190+
sandbox: &mut dyn Registerable,
152191
name: &str,
153192
) -> Result<()>;
154193

155194
/// Register the host function with the given name in the sandbox, allowing extra syscalls.
156195
#[cfg(all(feature = "seccomp", target_os = "linux"))]
157196
fn register_with_extra_allowed_syscalls(
158197
&self,
159-
sandbox: &mut UninitializedSandbox,
198+
sandbox: &mut dyn Registerable,
160199
name: &str,
161200
extra_allowed_syscalls: Vec<ExtraAllowedSyscall>,
162201
) -> Result<()>;
@@ -173,7 +212,7 @@ macro_rules! host_function {
173212
)]
174213
fn register(
175214
&self,
176-
sandbox: &mut UninitializedSandbox,
215+
sandbox: &mut dyn Registerable,
177216
name: &str,
178217
) -> Result<()> {
179218
[<register_host_function_ $N>](self.clone(), sandbox, name, None)
@@ -186,7 +225,7 @@ macro_rules! host_function {
186225
)]
187226
fn register_with_extra_allowed_syscalls(
188227
&self,
189-
sandbox: &mut UninitializedSandbox,
228+
sandbox: &mut dyn Registerable,
190229
name: &str,
191230
extra_allowed_syscalls: Vec<ExtraAllowedSyscall>,
192231
) -> Result<()> {
@@ -196,7 +235,7 @@ macro_rules! host_function {
196235

197236
fn [<register_host_function_ $N>]<'a, T, $($P,)* R>(
198237
self_: Arc<Mutex<T>>,
199-
sandbox: &mut UninitializedSandbox,
238+
sandbox: &mut dyn Registerable,
200239
name: &str,
201240
extra_allowed_syscalls: Option<Vec<ExtraAllowedSyscall>>,
202241
) -> Result<()>
@@ -231,40 +270,30 @@ macro_rules! host_function {
231270
// Register with extra allowed syscalls
232271
#[cfg(all(feature = "seccomp", target_os = "linux"))]
233272
{
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-
),
273+
sandbox.register_host_function_with_syscalls(
274+
&HostFunctionDefinition::new(
275+
name.to_string(),
276+
parameter_types,
277+
R::get_hyperlight_type(),
278+
),
245279
HyperlightFunction::new(func),
246-
_eas,
247-
)?;
280+
_eas,
281+
)?;
248282
}
249283
} else {
250284
// Log and return an error
251285
log_then_return!("Extra allowed syscalls are only supported on Linux with seccomp enabled");
252286
}
253287
} else {
254288
// 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-
)?;
289+
sandbox.register_host_function(
290+
&HostFunctionDefinition::new(
291+
name.to_string(),
292+
parameter_types,
293+
R::get_hyperlight_type(),
294+
),
295+
HyperlightFunction::new(func),
296+
)?;
268297
}
269298

270299
Ok(())

0 commit comments

Comments
 (0)