#![allow(clippy::undocumented_unsafe_blocks)]
use std::collections::BTreeMap;
use std::sync::mpsc::sync_channel;
use std::thread;
use seccompiler::{
apply_filter_all_threads, BpfProgram, SeccompAction, SeccompFilter, SeccompRule,
};
use std::env::consts::ARCH;
fn check_getpid_fails() {
let pid = unsafe { libc::getpid() };
let errno = std::io::Error::last_os_error().raw_os_error().unwrap();
assert_eq!(pid, -1, "getpid should return -1 as set in SeccompFilter");
assert_eq!(errno, 0, "there should be no errors");
}
#[test]
fn test_tsync() {
let (setup_tx, setup_rx) = sync_channel::<()>(0);
let (finish_tx, finish_rx) = sync_channel::<()>(0);
let pid = unsafe { libc::getpid() };
let errno = std::io::Error::last_os_error().raw_os_error().unwrap();
assert!(pid > 0, "getpid should return the actual pid");
assert_eq!(errno, 0, "there should be no errors");
let seccomp_thread = thread::spawn(move || {
let rules = vec![(libc::SYS_getpid, vec![])];
let rule_map: BTreeMap<i64, Vec<SeccompRule>> = rules.into_iter().collect();
let filter = SeccompFilter::new(
rule_map,
SeccompAction::Allow,
SeccompAction::Errno(1u32),
ARCH.try_into().unwrap(),
)
.unwrap();
let filter: BpfProgram = filter.try_into().unwrap();
apply_filter_all_threads(&filter).unwrap();
check_getpid_fails();
setup_tx.send(()).unwrap();
finish_rx.recv().unwrap();
println!("exit seccomp thread");
});
let test_thread = thread::spawn(move || {
setup_rx.recv().unwrap();
check_getpid_fails();
finish_tx.send(()).unwrap();
println!("exit io thread");
});
let seccomp_res = seccomp_thread.join();
assert!(
seccomp_res.is_ok(),
"seccomp thread failed: {:?}",
seccomp_res.unwrap_err()
);
let test_res = test_thread.join();
assert!(
test_res.is_ok(),
"test thread failed: {:?}",
test_res.unwrap_err()
);
check_getpid_fails();
}