From aae146bf3a5937dae16a9029701eda4a215eca19 Mon Sep 17 00:00:00 2001 From: Serban Iorga Date: Wed, 11 Sep 2019 17:59:16 +0300 Subject: [PATCH] use SECCOMP_RET_ERRNO in seccomp unit tests We have some seccomp unit tests that rely on SECCOMP_RET_KILL. By changing them to use SECCOMP_RET_ERRNO instead we make them simpler and more reliable. Signed-off-by: Serban Iorga --- seccomp/src/lib.rs | 76 ++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 43 deletions(-) diff --git a/seccomp/src/lib.rs b/seccomp/src/lib.rs index 03ca94a9043..71200911b7a 100644 --- a/seccomp/src/lib.rs +++ b/seccomp/src/lib.rs @@ -1133,8 +1133,6 @@ fn EXAMINE_SYSCALL() -> Vec { #[cfg(test)] mod tests { use super::*; - use std::sync::atomic::{AtomicBool, Ordering}; - use std::sync::Arc; use std::thread; use SeccompCmpArgLen as ArgLen; use SeccompCmpOp::*; @@ -1165,53 +1163,45 @@ mod tests { fn validate_seccomp_filter( rules: Vec<(i64, Vec)>, validation_fn: fn(), - should_trigger_sigsys: bool, + should_fail: bool, ) { - let mut filter = - SeccompFilter::new(rules.into_iter().collect(), SeccompAction::Kill).unwrap(); - - let triggered_sigsys: Arc = Arc::new(AtomicBool::new(true)); - let shared_triggered_sigsys = triggered_sigsys.clone(); - - // We need 2 threads here: in case of a seccomp denial, the inner thread will be killed - // and the outter thread will fail. The execution will be returned to the instruction - // that follows the outter thread `join()` method. - let outter_thread = thread::spawn(move || { - let inner_thread = thread::spawn(move || { - // whitelist needed syscalls - for syscall in EXTRA_SYSCALLS.iter() { - assert!(filter - .add_rules( - *syscall, - vec![SeccompRule::new(vec![], SeccompAction::Allow)], - ) - .is_ok()); - } - // apply filter - assert!(filter.apply().is_ok()); + let failure_code: i32 = 1000; + // Build seccomp filter. + let mut filter = SeccompFilter::new( + rules.into_iter().collect(), + SeccompAction::Errno(failure_code as u32), + ) + .unwrap(); + for syscall in EXTRA_SYSCALLS.iter() { + filter + .add_rules( + *syscall, + vec![SeccompRule::new(vec![], SeccompAction::Allow)], + ) + .unwrap(); + } - // call validation fn - validation_fn(); + // We need to run the validation inside another thread in order to avoid setting + // the seccomp filter for the entire unit tests process. + let errno = thread::spawn(move || { + // Apply seccomp filter. + filter.apply().unwrap(); - // if we reach this point, then SIGSYS hasn't been triggered - shared_triggered_sigsys.store(false, Ordering::Relaxed); - }) - .join(); + // Call the validation fn. + validation_fn(); - if !should_trigger_sigsys { - assert!(inner_thread.is_ok()); - } + // Return errno. + std::io::Error::last_os_error().raw_os_error().unwrap() }) - .join(); - - if !should_trigger_sigsys { - assert!(outter_thread.is_ok()); + .join() + .unwrap(); + + // In case of a seccomp denial `errno` should be `failure_code` + if should_fail { + assert_eq!(errno, failure_code); + } else { + assert_ne!(errno, failure_code); } - - assert_eq!( - triggered_sigsys.load(Ordering::Relaxed), - should_trigger_sigsys - ); } #[test]