@@ -295,10 +295,14 @@ where
295295
296296#[ cfg( test) ]
297297mod tests {
298+ use std:: thread;
299+
300+ use crate :: Result ;
301+ use crate :: { is_hypervisor_present, HyperlightError } ;
298302 use hyperlight_common:: flatbuffer_wrappers:: function_types:: {
299303 ParameterValue , ReturnType , ReturnValue ,
300304 } ;
301- use hyperlight_testing:: simple_guest_as_string;
305+ use hyperlight_testing:: { callback_guest_as_string , simple_guest_as_string} ;
302306
303307 use crate :: func:: call_ctx:: MultiUseGuestCallContext ;
304308 use crate :: sandbox:: SandboxConfiguration ;
@@ -384,4 +388,161 @@ mod tests {
384388 . unwrap ( ) ;
385389 assert_eq ! ( res, ReturnValue :: Int ( 0 ) ) ;
386390 }
391+
392+ #[ test]
393+ // TODO: Investigate why this test fails with an incorrect error when run alongside other tests
394+ #[ ignore]
395+ fn test_violate_seccomp_filters ( ) -> Result < ( ) > {
396+ if cfg ! ( target_os = "windows" ) {
397+ // This test is not applicable on Windows as seccomp is a Linux-specific feature.
398+ return Ok ( ( ) ) ;
399+ }
400+
401+ if !is_hypervisor_present ( ) {
402+ panic ! ( "Panic on create_multi_use_sandbox because no hypervisor is present" ) ;
403+ }
404+
405+ fn make_get_pid_syscall ( ) -> Result < u64 > {
406+ let pid = unsafe { libc:: syscall ( libc:: SYS_getpid ) } ;
407+ Ok ( pid as u64 )
408+ }
409+
410+ // First, run to make sure it fails.
411+ {
412+ let mut usbox = UninitializedSandbox :: new (
413+ GuestBinary :: FilePath ( simple_guest_as_string ( ) . expect ( "Guest Binary Missing" ) ) ,
414+ None ,
415+ )
416+ . unwrap ( ) ;
417+
418+ usbox. register ( "MakeGetpidSyscall" , make_get_pid_syscall) ?;
419+
420+ let mut sbox: MultiUseSandbox = usbox. evolve ( Noop :: default ( ) ) ?;
421+
422+ let res =
423+ sbox. call_guest_function_by_name ( "ViolateSeccompFilters" , ReturnType :: ULong , None ) ;
424+
425+ #[ cfg( feature = "seccomp" ) ]
426+ match res {
427+ Ok ( _) => panic ! ( "Expected to fail due to seccomp violation" ) ,
428+ Err ( e) => match e {
429+ HyperlightError :: DisallowedSyscall => { }
430+ _ => panic ! ( "Expected DisallowedSyscall error: {}" , e) ,
431+ } ,
432+ }
433+
434+ #[ cfg( not( feature = "seccomp" ) ) ]
435+ match res {
436+ Ok ( _) => ( ) ,
437+ Err ( e) => panic ! ( "Expected to succeed without seccomp: {}" , e) ,
438+ }
439+ }
440+
441+ // Second, run with allowing `SYS_getpid`
442+ #[ cfg( feature = "seccomp" ) ]
443+ {
444+ let mut usbox = UninitializedSandbox :: new (
445+ GuestBinary :: FilePath ( simple_guest_as_string ( ) . expect ( "Guest Binary Missing" ) ) ,
446+ None ,
447+ )
448+ . unwrap ( ) ;
449+
450+ usbox. register_with_extra_allowed_syscalls (
451+ "MakeGetpidSyscall" ,
452+ make_get_pid_syscall,
453+ vec ! [ libc:: SYS_getpid ] ,
454+ ) ?;
455+ // ^^^ note, we are allowing SYS_getpid
456+
457+ let mut sbox: MultiUseSandbox = usbox. evolve ( Noop :: default ( ) ) ?;
458+
459+ let res =
460+ sbox. call_guest_function_by_name ( "ViolateSeccompFilters" , ReturnType :: ULong , None ) ;
461+
462+ match res {
463+ Ok ( _) => { }
464+ Err ( e) => panic ! ( "Expected to succeed due to seccomp violation: {}" , e) ,
465+ }
466+ }
467+
468+ Ok ( ( ) )
469+ }
470+
471+ // This test is to capture the case where the guest execution is running a host function when cancelled and that host function
472+ // is never going to return.
473+ // The host function that is called will end after 5 seconds, but by this time the cancellation will have given up
474+ // (using default timeout settings) , so this tests looks for the error "Failed to cancel guest execution".
475+ #[ test]
476+ #[ ignore = "We cannot cancel host functions. TODO reenable this test when it's enabled" ]
477+ fn test_terminate_vcpu_calling_host_spinning_cpu ( ) {
478+ // This test relies upon a Hypervisor being present so for now
479+ // we will skip it if there isn't one.
480+ if !is_hypervisor_present ( ) {
481+ println ! ( "Skipping test_call_guest_function_by_name because no hypervisor is present" ) ;
482+ return ;
483+ }
484+ let mut usbox = UninitializedSandbox :: new (
485+ GuestBinary :: FilePath ( callback_guest_as_string ( ) . expect ( "Guest Binary Missing" ) ) ,
486+ None ,
487+ )
488+ . unwrap ( ) ;
489+
490+ // Make this host call run for 5 seconds
491+
492+ fn spin ( ) -> Result < ( ) > {
493+ thread:: sleep ( std:: time:: Duration :: from_secs ( 5 ) ) ;
494+ Ok ( ( ) )
495+ }
496+
497+ #[ cfg( any( target_os = "windows" , not( feature = "seccomp" ) ) ) ]
498+ usbox. register ( "Spin" , spin) . unwrap ( ) ;
499+
500+ #[ cfg( all( target_os = "linux" , feature = "seccomp" ) ) ]
501+ usbox
502+ . register_with_extra_allowed_syscalls ( "Spin" , spin, vec ! [ libc:: SYS_clock_nanosleep ] )
503+ . unwrap ( ) ;
504+
505+ let sandbox: MultiUseSandbox = usbox. evolve ( Noop :: default ( ) ) . unwrap ( ) ;
506+ let mut ctx = sandbox. new_call_context ( ) ;
507+ let result = ctx. call ( "CallHostSpin" , ReturnType :: Void , None ) ;
508+
509+ assert ! ( result. is_err( ) ) ;
510+ match result. unwrap_err ( ) {
511+ HyperlightError :: GuestExecutionHungOnHostFunctionCall ( ) => { }
512+ e => panic ! (
513+ "Expected HyperlightError::GuestExecutionHungOnHostFunctionCall but got {:?}" ,
514+ e
515+ ) ,
516+ }
517+ }
518+
519+ #[ test]
520+ fn test_trigger_exception_on_guest ( ) {
521+ let usbox = UninitializedSandbox :: new (
522+ GuestBinary :: FilePath ( simple_guest_as_string ( ) . expect ( "Guest Binary Missing" ) ) ,
523+ None ,
524+ )
525+ . unwrap ( ) ;
526+
527+ let mut multi_use_sandbox: MultiUseSandbox = usbox. evolve ( Noop :: default ( ) ) . unwrap ( ) ;
528+
529+ let res = multi_use_sandbox. call_guest_function_by_name (
530+ "TriggerException" ,
531+ ReturnType :: Void ,
532+ None ,
533+ ) ;
534+
535+ assert ! ( res. is_err( ) ) ;
536+
537+ match res. unwrap_err ( ) {
538+ HyperlightError :: GuestAborted ( _, msg) => {
539+ // msg should indicate we got an invalid opcode exception
540+ assert ! ( msg. contains( "InvalidOpcode" ) ) ;
541+ }
542+ e => panic ! (
543+ "Expected HyperlightError::GuestExecutionError but got {:?}" ,
544+ e
545+ ) ,
546+ }
547+ }
387548}
0 commit comments