@@ -28,22 +28,24 @@ use hyperlight_common::flatbuffer_wrappers::function_call::{FunctionCall, Functi
2828use hyperlight_common:: flatbuffer_wrappers:: function_types:: {
2929 ParameterValue , ReturnType , ReturnValue ,
3030} ;
31+ use hyperlight_common:: flatbuffer_wrappers:: guest_error:: ErrorCode ;
3132use hyperlight_common:: flatbuffer_wrappers:: util:: estimate_flatbuffer_capacity;
3233use tracing:: { Span , instrument} ;
3334
3435use super :: host_funcs:: FunctionRegistry ;
3536use super :: snapshot:: Snapshot ;
3637use super :: { Callable , WrapperGetter } ;
37- use crate :: HyperlightError :: SnapshotSandboxMismatch ;
38- use crate :: func:: guest_err:: check_for_guest_error;
38+ use crate :: HyperlightError :: { self , SnapshotSandboxMismatch } ;
3939use crate :: func:: { ParameterTuple , SupportedReturnType } ;
4040use crate :: hypervisor:: { Hypervisor , InterruptHandle } ;
4141#[ cfg( unix) ]
4242use crate :: mem:: memory_region:: MemoryRegionType ;
4343use crate :: mem:: memory_region:: { MemoryRegion , MemoryRegionFlags } ;
4444use crate :: mem:: ptr:: RawPtr ;
4545use crate :: mem:: shared_mem:: HostSharedMemory ;
46- use crate :: metrics:: maybe_time_and_emit_guest_call;
46+ use crate :: metrics:: {
47+ METRIC_GUEST_ERROR , METRIC_GUEST_ERROR_LABEL_CODE , maybe_time_and_emit_guest_call,
48+ } ;
4749use crate :: sandbox:: mem_mgr:: MemMgrWrapper ;
4850use crate :: { Result , log_then_return} ;
4951
@@ -418,11 +420,28 @@ impl MultiUseSandbox {
418420 ) ?;
419421
420422 self . mem_mgr . check_stack_guard ( ) ?;
421- check_for_guest_error ( self . get_mgr_wrapper_mut ( ) ) ?;
422423
423- self . get_mgr_wrapper_mut ( )
424+ let guest_result = self
425+ . get_mgr_wrapper_mut ( )
424426 . as_mut ( )
425- . get_guest_function_call_result ( )
427+ . get_guest_function_call_result ( ) ?
428+ . into_inner ( ) ;
429+
430+ match guest_result {
431+ Ok ( val) => Ok ( val) ,
432+ Err ( guest_error) => {
433+ metrics:: counter!(
434+ METRIC_GUEST_ERROR ,
435+ METRIC_GUEST_ERROR_LABEL_CODE => ( guest_error. code as u64 ) . to_string( )
436+ )
437+ . increment ( 1 ) ;
438+
439+ Err ( match guest_error. code {
440+ ErrorCode :: StackOverflow => HyperlightError :: StackOverflow ( ) ,
441+ _ => HyperlightError :: GuestError ( guest_error. code , guest_error. message ) ,
442+ } )
443+ }
444+ }
426445 } ) ( ) ;
427446
428447 // In the happy path we do not need to clear io-buffers from the host because:
@@ -512,6 +531,36 @@ mod tests {
512531 use crate :: sandbox:: SandboxConfiguration ;
513532 use crate :: { GuestBinary , HyperlightError , MultiUseSandbox , Result , UninitializedSandbox } ;
514533
534+ /// Make sure input/output buffers are properly reset after guest call (with host call)
535+ #[ test]
536+ #[ ignore = "added this test before fixing bug" ]
537+ fn host_func_error ( ) {
538+ let path = simple_guest_as_string ( ) . unwrap ( ) ;
539+ let mut sandbox = UninitializedSandbox :: new ( GuestBinary :: FilePath ( path) , None ) . unwrap ( ) ;
540+ sandbox
541+ . register ( "HostError" , || -> Result < ( ) > {
542+ Err ( HyperlightError :: Error ( "hi" . to_string ( ) ) )
543+ } )
544+ . unwrap ( ) ;
545+ let mut sandbox = sandbox. evolve ( ) . unwrap ( ) ;
546+
547+ // will exhaust io if leaky
548+ for _ in 0 ..1000 {
549+ let result = sandbox
550+ . call :: < i64 > (
551+ "CallGivenParamlessHostFuncThatReturnsI64" ,
552+ "HostError" . to_string ( ) ,
553+ )
554+ . unwrap_err ( ) ;
555+
556+ assert ! (
557+ matches!( result, HyperlightError :: Error ( ref msg) if msg == "hi" ) ,
558+ "Expected HyperlightError::Error('hi'), got {:?}" ,
559+ result
560+ ) ;
561+ }
562+ }
563+
515564 /// Make sure input/output buffers are properly reset after guest call (with host call)
516565 #[ test]
517566 fn io_buffer_reset ( ) {
@@ -625,6 +674,9 @@ mod tests {
625674 #[ ignore]
626675 #[ cfg( target_os = "linux" ) ]
627676 fn test_violate_seccomp_filters ( ) -> Result < ( ) > {
677+ #[ cfg( feature = "seccomp" ) ]
678+ use hyperlight_common:: flatbuffer_wrappers:: guest_error:: ErrorCode ;
679+
628680 fn make_get_pid_syscall ( ) -> Result < u64 > {
629681 let pid = unsafe { libc:: syscall ( libc:: SYS_getpid ) } ;
630682 Ok ( pid as u64 )
@@ -648,7 +700,9 @@ mod tests {
648700 match res {
649701 Ok ( _) => panic ! ( "Expected to fail due to seccomp violation" ) ,
650702 Err ( e) => match e {
651- HyperlightError :: DisallowedSyscall => { }
703+ HyperlightError :: GuestError ( t, msg)
704+ if t == ErrorCode :: HostFunctionError
705+ && msg. contains ( "Seccomp filter trapped on disallowed syscall" ) => { }
652706 _ => panic ! ( "Expected DisallowedSyscall error: {}" , e) ,
653707 } ,
654708 }
0 commit comments