@@ -30,7 +30,7 @@ use super::mem_mgr::MemMgrWrapper;
3030use super :: run_options:: SandboxRunOptions ;
3131use super :: uninitialized_evolve:: evolve_impl_multi_use;
3232use crate :: error:: HyperlightError :: GuestBinaryShouldBeAFile ;
33- use crate :: func:: host_functions:: HostFunction ;
33+ use crate :: func:: host_functions:: { HostFunction , IntoHostFunction } ;
3434use crate :: mem:: exe:: ExeInfo ;
3535use crate :: mem:: mgr:: { SandboxMemoryManager , STACK_COOKIE_LEN } ;
3636use crate :: mem:: shared_mem:: ExclusiveSharedMemory ;
@@ -224,24 +224,15 @@ impl UninitializedSandbox {
224224 // If we were passed a writer for host print register it otherwise use the default.
225225 match host_print_writer {
226226 Some ( writer_func) => {
227- #[ allow( clippy:: arc_with_non_send_sync) ]
228- let writer_func = Arc :: new ( Mutex :: new ( writer_func) ) ;
229-
230227 #[ cfg( any( target_os = "windows" , not( feature = "seccomp" ) ) ) ]
231- writer_func
232- . try_lock ( )
233- . map_err ( |e| new_error ! ( "Error locking at {}:{}: {}" , file!( ) , line!( ) , e) ) ?
234- . register ( & mut sandbox, "HostPrint" ) ?;
228+ writer_func. register ( & mut sandbox, "HostPrint" ) ?;
235229
236230 #[ cfg( all( target_os = "linux" , feature = "seccomp" ) ) ]
237- writer_func
238- . try_lock ( )
239- . map_err ( |e| new_error ! ( "Error locking at {}:{}: {}" , file!( ) , line!( ) , e) ) ?
240- . register_with_extra_allowed_syscalls (
241- & mut sandbox,
242- "HostPrint" ,
243- extra_allowed_syscalls_for_writer_func,
244- ) ?;
231+ writer_func. register_with_extra_allowed_syscalls (
232+ & mut sandbox,
233+ "HostPrint" ,
234+ extra_allowed_syscalls_for_writer_func,
235+ ) ?;
245236 }
246237 None => {
247238 let default_writer = Arc :: new ( Mutex :: new ( default_writer_func) ) ;
@@ -309,6 +300,31 @@ impl UninitializedSandbox {
309300 pub fn set_max_guest_log_level ( & mut self , log_level : LevelFilter ) {
310301 self . max_guest_log_level = Some ( log_level) ;
311302 }
303+
304+ /// Register a host function with the given name in the sandbox.
305+ pub fn register < F , R , Args > ( & mut self , name : impl AsRef < str > , host_func : F ) -> Result < ( ) >
306+ where
307+ F : IntoHostFunction < R , Args > ,
308+ {
309+ host_func. into_host_function ( ) . register ( self , name. as_ref ( ) )
310+ }
311+
312+ /// Register the host function with the given name in the sandbox, allowing extra syscalls.
313+ #[ cfg( all( feature = "seccomp" , target_os = "linux" ) ) ]
314+ pub fn register_with_extra_allowed_syscalls < F , R , Args > (
315+ & mut self ,
316+ name : impl AsRef < str > ,
317+ host_func : F ,
318+ extra_allowed_syscalls : impl IntoIterator < Item = crate :: sandbox:: ExtraAllowedSyscall > ,
319+ ) -> Result < ( ) >
320+ where
321+ F : IntoHostFunction < R , Args > ,
322+ {
323+ let extra_allowed_syscalls: Vec < _ > = extra_allowed_syscalls. into_iter ( ) . collect ( ) ;
324+ host_func
325+ . into_host_function ( )
326+ . register_with_extra_allowed_syscalls ( self , name. as_ref ( ) , extra_allowed_syscalls)
327+ }
312328}
313329// Check to see if the current version of Windows is supported
314330// Hyperlight is only supported on Windows 11 and Windows Server 2022 and later
@@ -355,7 +371,6 @@ mod tests {
355371 use tracing_core:: Subscriber ;
356372 use uuid:: Uuid ;
357373
358- use crate :: func:: HostFunction ;
359374 use crate :: sandbox:: uninitialized:: GuestBinary ;
360375 use crate :: sandbox:: SandboxConfiguration ;
361376 use crate :: sandbox_state:: sandbox:: EvolvableSandbox ;
@@ -516,9 +531,8 @@ mod tests {
516531 // simple register + call
517532 {
518533 let mut usbox = uninitialized_sandbox ( ) ;
519- let test0 = |arg : i32 | -> Result < i32 > { Ok ( arg + 1 ) } ;
520- let test_func0 = Arc :: new ( Mutex :: new ( test0) ) ;
521- test_func0. register ( & mut usbox, "test0" ) . unwrap ( ) ;
534+
535+ usbox. register ( "test0" , |arg : i32 | Ok ( arg + 1 ) ) . unwrap ( ) ;
522536
523537 let sandbox: Result < MultiUseSandbox > = usbox. evolve ( Noop :: default ( ) ) ;
524538 assert ! ( sandbox. is_ok( ) ) ;
@@ -542,9 +556,8 @@ mod tests {
542556 // multiple parameters register + call
543557 {
544558 let mut usbox = uninitialized_sandbox ( ) ;
545- let test1 = |arg1 : i32 , arg2 : i32 | -> Result < i32 > { Ok ( arg1 + arg2) } ;
546- let test_func1 = Arc :: new ( Mutex :: new ( test1) ) ;
547- test_func1. register ( & mut usbox, "test1" ) . unwrap ( ) ;
559+
560+ usbox. register ( "test1" , |a : i32 , b : i32 | Ok ( a + b) ) . unwrap ( ) ;
548561
549562 let sandbox: Result < MultiUseSandbox > = usbox. evolve ( Noop :: default ( ) ) ;
550563 assert ! ( sandbox. is_ok( ) ) ;
@@ -571,12 +584,13 @@ mod tests {
571584 // incorrect arguments register + call
572585 {
573586 let mut usbox = uninitialized_sandbox ( ) ;
574- let test2 = |arg1 : String | -> Result < ( ) > {
575- println ! ( "test2 called: {}" , arg1) ;
576- Ok ( ( ) )
577- } ;
578- let test_func2 = Arc :: new ( Mutex :: new ( test2) ) ;
579- test_func2. register ( & mut usbox, "test2" ) . unwrap ( ) ;
587+
588+ usbox
589+ . register ( "test2" , |msg : String | {
590+ println ! ( "test2 called: {}" , msg) ;
591+ Ok ( ( ) )
592+ } )
593+ . unwrap ( ) ;
580594
581595 let sandbox: Result < MultiUseSandbox > = usbox. evolve ( Noop :: default ( ) ) ;
582596 assert ! ( sandbox. is_ok( ) ) ;
0 commit comments