From ec63a5c979d407fab9052fffd6f0e2fd6dc1a406 Mon Sep 17 00:00:00 2001 From: yihuaf Date: Wed, 29 Sep 2021 07:58:00 +0200 Subject: [PATCH 1/4] Implemented a helper function to run tests in child process --- Cargo.lock | 311 +++++++++++++++++++++++++++++++++++++++++++++++---- Cargo.toml | 1 + src/utils.rs | 52 ++++++++- 3 files changed, 339 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 399dfce4d..08d735e6d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,7 +23,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -46,7 +46,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -55,6 +55,15 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bitflags" version = "1.2.1" @@ -135,7 +144,7 @@ dependencies = [ "num-traits", "serde", "time", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -201,6 +210,16 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "crossbeam-channel" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87" +dependencies = [ + "crossbeam-utils 0.7.2", + "maybe-uninit", +] + [[package]] name = "crossbeam-channel" version = "0.5.1" @@ -208,7 +227,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" dependencies = [ "cfg-if 1.0.0", - "crossbeam-utils", + "crossbeam-utils 0.8.5", +] + +[[package]] +name = "crossbeam-utils" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +dependencies = [ + "autocfg", + "cfg-if 0.1.10", + "lazy_static", ] [[package]] @@ -274,7 +304,7 @@ checksum = "c8862bb50aa3b2a2db5bfd2c875c73b3038aa931c411087e335ca8ca0ed430b9" dependencies = [ "libc", "libdbus-sys", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -339,7 +369,7 @@ checksum = "fa68f2fb9cae9d37c9b2b3584aba698a2e97f72d7aef7b9f7aa71d8b54ce46fe" dependencies = [ "errno-dragonfly", "libc", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -406,6 +436,22 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7684cf33bb7f28497939e8c7cf17e3e4e3b8d9a0080ffa4f8ae2f515442ee855" +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +dependencies = [ + "bitflags", + "fuchsia-zircon-sys", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" + [[package]] name = "futures" version = "0.3.17" @@ -507,6 +553,17 @@ version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + [[package]] name = "getrandom" version = "0.2.3" @@ -515,7 +572,7 @@ checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ "cfg-if 1.0.0", "libc", - "wasi", + "wasi 0.10.2+wasi-snapshot-preview1", ] [[package]] @@ -591,12 +648,50 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +dependencies = [ + "libc", +] + +[[package]] +name = "ipc-channel" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad9b32d360ae2d4662212f1d29bc8a277256f49029cea20fd6c182b89819aea7" +dependencies = [ + "bincode", + "crossbeam-channel 0.4.4", + "fnv", + "lazy_static", + "libc", + "mio 0.6.23", + "rand 0.7.3", + "serde", + "tempfile", + "uuid", + "winapi 0.3.9", +] + [[package]] name = "itoa" version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -657,6 +752,12 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + [[package]] name = "memchr" version = "2.4.1" @@ -682,6 +783,25 @@ dependencies = [ "autocfg", ] +[[package]] +name = "mio" +version = "0.6.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" +dependencies = [ + "cfg-if 0.1.10", + "fuchsia-zircon", + "fuchsia-zircon-sys", + "iovec", + "kernel32-sys", + "libc", + "log", + "miow 0.2.2", + "net2", + "slab", + "winapi 0.2.8", +] + [[package]] name = "mio" version = "0.7.13" @@ -690,9 +810,21 @@ checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16" dependencies = [ "libc", "log", - "miow", + "miow 0.3.7", "ntapi", - "winapi", + "winapi 0.3.9", +] + +[[package]] +name = "miow" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" +dependencies = [ + "kernel32-sys", + "net2", + "winapi 0.2.8", + "ws2_32-sys", ] [[package]] @@ -701,7 +833,18 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" dependencies = [ - "winapi", + "winapi 0.3.9", +] + +[[package]] +name = "net2" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "winapi 0.3.9", ] [[package]] @@ -723,7 +866,7 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -802,7 +945,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -823,6 +966,12 @@ version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + [[package]] name = "prctl" version = "1.0.0" @@ -901,7 +1050,7 @@ checksum = "588f6378e4dd99458b60ec275b4477add41ce4fa9f64dcba6f15adccb19b50d6" dependencies = [ "env_logger 0.8.4", "log", - "rand", + "rand 0.8.4", ] [[package]] @@ -913,13 +1062,58 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", +] + [[package]] name = "rand" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" dependencies = [ - "rand_core", + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.3", + "rand_hc 0.3.1", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.3", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", ] [[package]] @@ -928,7 +1122,25 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ - "getrandom", + "getrandom 0.2.3", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core 0.6.3", ] [[package]] @@ -969,6 +1181,15 @@ version = "0.6.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi 0.3.9", +] + [[package]] name = "ryu" version = "1.0.5" @@ -1100,6 +1321,20 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "tempfile" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "rand 0.8.4", + "redox_syscall", + "remove_dir_all", + "winapi 0.3.9", +] + [[package]] name = "termcolor" version = "1.1.2" @@ -1151,7 +1386,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" dependencies = [ "libc", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1178,6 +1413,15 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55bcbb425141152b10d5693095950b51c3745d019363fc2929ffd8f61449b628" +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom 0.2.3", +] + [[package]] name = "vec_map" version = "0.8.2" @@ -1190,12 +1434,24 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + [[package]] name = "wasi" version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" + [[package]] name = "winapi" version = "0.3.9" @@ -1206,6 +1462,12 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" + [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -1218,7 +1480,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1227,6 +1489,16 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + [[package]] name = "youki" version = "0.0.1" @@ -1236,13 +1508,14 @@ dependencies = [ "cgroups", "chrono", "clap 3.0.0-beta.4", - "crossbeam-channel", + "crossbeam-channel 0.5.1", "dbus", "fastrand", "futures", + "ipc-channel", "libc", "log", - "mio", + "mio 0.7.13", "nix", "oci-spec", "once_cell", diff --git a/Cargo.toml b/Cargo.toml index a3ccfde9f..dfa3f8614 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,6 +50,7 @@ tabwriter = "1" fastrand = "1.4.1" crossbeam-channel = "0.5" seccomp = { version = "0.1.0", path = "./seccomp" } +ipc-channel = "0.15.0" [dev-dependencies] # TODO: Fetch from crate.io instead of git when next release oci-spec-rs diff --git a/src/utils.rs b/src/utils.rs index 653ec84db..403c63a4d 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,5 +1,13 @@ //! Utility functionality +use anyhow::Context; +use anyhow::{bail, Result}; +use ipc_channel::ipc; +use nix::sys::stat::Mode; +use nix::sys::statfs; +use nix::sys::wait; +use nix::unistd; +use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::ffi::CString; use std::fs::{self, DirBuilder, File}; @@ -10,12 +18,6 @@ use std::os::unix::prelude::AsRawFd; use std::path::{Path, PathBuf}; use std::time::Duration; -use anyhow::Context; -use anyhow::{bail, Result}; -use nix::sys::stat::Mode; -use nix::sys::statfs; -use nix::unistd; - pub trait PathBufExt { fn as_in_container(&self) -> Result; fn join_absolute_path(&self, p: &Path) -> Result; @@ -216,6 +218,44 @@ pub fn create_temp_dir(test_name: &str) -> Result { Ok(dir) } +#[derive(Debug, Serialize, Deserialize)] +struct TestResult { + success: bool, + message: String, +} + +pub fn test_in_child_process Result<()>>(cb: F) -> Result<()> { + let (sender, receiver) = ipc::channel::()?; + match unsafe { nix::unistd::fork()? } { + nix::unistd::ForkResult::Parent { child } => { + let res = receiver.recv().unwrap(); + wait::waitpid(child, None)?; + + if !res.success { + bail!("child process failed: {}", res.message); + } + } + nix::unistd::ForkResult::Child => { + let test_result = match cb() { + Ok(_) => TestResult { + success: true, + message: String::new(), + }, + Err(err) => TestResult { + success: false, + message: err.to_string(), + }, + }; + sender + .send(test_result) + .context("failed to send from the child process")?; + std::process::exit(0); + } + }; + + Ok(()) +} + #[cfg(test)] mod tests { use super::*; From 0198cc6ae770c8d1b3b0a8bd9b70e260be3e99ee Mon Sep 17 00:00:00 2001 From: yihuaf Date: Wed, 29 Sep 2021 07:58:19 +0200 Subject: [PATCH 2/4] Implemented seccomp test using the new test utils --- src/seccomp/mod.rs | 116 ++++++++++++--------------------------------- 1 file changed, 31 insertions(+), 85 deletions(-) diff --git a/src/seccomp/mod.rs b/src/seccomp/mod.rs index 5dd3f4410..fef966531 100644 --- a/src/seccomp/mod.rs +++ b/src/seccomp/mod.rs @@ -382,15 +382,11 @@ pub fn initialize_seccomp(seccomp: &LinuxSeccomp) -> Result> { #[cfg(test)] mod tests { use super::*; + use crate::utils; use anyhow::Result; - use mio::unix::pipe; - use nix::sys::wait; use oci_spec::runtime::Arch; use oci_spec::runtime::{LinuxSeccompBuilder, LinuxSyscallBuilder}; use serial_test::serial; - use std::io::Read; - use std::io::Write; - use std::os::unix::prelude::AsRawFd; use std::path; #[test] @@ -419,40 +415,24 @@ mod tests { .syscalls(vec![syscall]) .build()?; - // Since Rust cargo test uses a single process to execute all tests, it - // is a good idea to fork a child process to test the seccomp profile, - // and then kill the process. This way, the main test process is - // unaffected. The child process will pass the returned error code - // to the parent for assert and checking. - let (mut sender, mut receiver) = pipe::new()?; - receiver - .set_nonblocking(false) - .with_context(|| "Failed to set channel receiver to blocking")?; - - match unsafe { nix::unistd::fork()? } { - nix::unistd::ForkResult::Parent { child } => { - nix::unistd::close(sender.as_raw_fd())?; - let mut buf = [0; 4]; - receiver - .read_exact(&mut buf) - .context("Failed to wait from child")?; - assert_eq!(i32::from_be_bytes(buf), expect_error); - wait::waitpid(child, None)?; + utils::test_in_child_process(|| { + let _ = prctl::set_no_new_privileges(true); + initialize_seccomp(&seccomp_profile)?; + let ret = nix::unistd::getcwd(); + if ret.is_ok() { + bail!("getcwd didn't error out as seccomp profile specified"); } - nix::unistd::ForkResult::Child => { - nix::unistd::close(receiver.as_raw_fd())?; - let _ = prctl::set_no_new_privileges(true); - initialize_seccomp(&seccomp_profile)?; - let ret = nix::unistd::getcwd(); - let errno: i32 = if ret.is_err() { - ret.err().unwrap() as i32 - } else { - 0 - }; - sender.write_all(&errno.to_be_bytes())?; - std::process::exit(errno); + + if let Some(errno) = ret.err() { + if errno != nix::errno::from_i32(expect_error) { + bail!( + "getcwd failed but we didn't get the expected error from seccomp profile: {}", errno + ); + } } - } + + Ok(()) + })?; Ok(()) } @@ -467,28 +447,12 @@ mod tests { // We know linux and seccomp exist, so let's just unwrap. let seccomp_profile = spec.linux().as_ref().unwrap().seccomp().as_ref().unwrap(); - match unsafe { nix::unistd::fork()? } { - nix::unistd::ForkResult::Parent { child } => { - let status = wait::waitpid(child, None)?; - match status { - wait::WaitStatus::Exited(_, exit_code) => { - assert_eq!( - exit_code, 0, - "Child process didn't configure seccomp profile correctly" - ); - } - _ => { - bail!("Child process failed to exit correctly: {:?}", status); - } - } - } - nix::unistd::ForkResult::Child => { - let _ = prctl::set_no_new_privileges(true); - let ret = initialize_seccomp(seccomp_profile); - let exit_code = if ret.is_ok() { 0 } else { -1 }; - std::process::exit(exit_code); - } - } + utils::test_in_child_process(|| { + let _ = prctl::set_no_new_privileges(true); + initialize_seccomp(&seccomp_profile)?; + + Ok(()) + })?; Ok(()) } @@ -505,33 +469,15 @@ mod tests { .architectures(vec![Arch::ScmpArchNative]) .syscalls(vec![syscall]) .build()?; - - match unsafe { nix::unistd::fork()? } { - nix::unistd::ForkResult::Parent { child } => { - let status = wait::waitpid(child, None)?; - match status { - wait::WaitStatus::Exited(_, exit_code) => { - assert_eq!( - exit_code, 0, - "Child process didn't configure seccomp profile correctly" - ); - } - _ => { - bail!("Child process failed to exit correctly: {:?}", status); - } - } - } - nix::unistd::ForkResult::Child => { - let _ = prctl::set_no_new_privileges(true); - let fd = initialize_seccomp(&seccomp_profile)?; - - if fd.is_some() { - std::process::exit(0) - } else { - std::process::exit(-1); - } + utils::test_in_child_process(|| { + let _ = prctl::set_no_new_privileges(true); + let fd = initialize_seccomp(&seccomp_profile)?; + if fd.is_none() { + bail!("failed to get a seccomp notify fd with notify seccomp profile"); } - } + + Ok(()) + })?; Ok(()) } From 6850ee62f771af2d661e7e7ccf180cc8eaf16e4b Mon Sep 17 00:00:00 2001 From: yihuaf Date: Wed, 29 Sep 2021 08:04:59 +0200 Subject: [PATCH 3/4] clippy happy --- src/seccomp/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/seccomp/mod.rs b/src/seccomp/mod.rs index fef966531..494e99b3a 100644 --- a/src/seccomp/mod.rs +++ b/src/seccomp/mod.rs @@ -449,7 +449,7 @@ mod tests { let seccomp_profile = spec.linux().as_ref().unwrap().seccomp().as_ref().unwrap(); utils::test_in_child_process(|| { let _ = prctl::set_no_new_privileges(true); - initialize_seccomp(&seccomp_profile)?; + initialize_seccomp(seccomp_profile)?; Ok(()) })?; From 6d4bda689d012f8fbaedbf6e99e957438c70c74b Mon Sep 17 00:00:00 2001 From: yihuaf Date: Thu, 30 Sep 2021 01:06:11 +0200 Subject: [PATCH 4/4] move ipc-channel to dev dependencies --- Cargo.toml | 2 +- src/seccomp/mod.rs | 8 ++--- src/utils.rs | 76 +++++++++++++++++++++++++--------------------- 3 files changed, 46 insertions(+), 40 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index dfa3f8614..2ea0a9497 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,7 +50,6 @@ tabwriter = "1" fastrand = "1.4.1" crossbeam-channel = "0.5" seccomp = { version = "0.1.0", path = "./seccomp" } -ipc-channel = "0.15.0" [dev-dependencies] # TODO: Fetch from crate.io instead of git when next release oci-spec-rs @@ -59,6 +58,7 @@ ipc-channel = "0.15.0" oci-spec = { git = "https://github.com/containers/oci-spec-rs", rev = "5018f8e5b0355a82c08962cefa5ab07a05b930c6", features = ["proptests"] } quickcheck = "1" serial_test = "0.5.1" +ipc-channel = "0.15.0" [profile.release] lto = true diff --git a/src/seccomp/mod.rs b/src/seccomp/mod.rs index 494e99b3a..72f585d27 100644 --- a/src/seccomp/mod.rs +++ b/src/seccomp/mod.rs @@ -382,7 +382,7 @@ pub fn initialize_seccomp(seccomp: &LinuxSeccomp) -> Result> { #[cfg(test)] mod tests { use super::*; - use crate::utils; + use crate::utils::test_utils; use anyhow::Result; use oci_spec::runtime::Arch; use oci_spec::runtime::{LinuxSeccompBuilder, LinuxSyscallBuilder}; @@ -415,7 +415,7 @@ mod tests { .syscalls(vec![syscall]) .build()?; - utils::test_in_child_process(|| { + test_utils::test_in_child_process(|| { let _ = prctl::set_no_new_privileges(true); initialize_seccomp(&seccomp_profile)?; let ret = nix::unistd::getcwd(); @@ -447,7 +447,7 @@ mod tests { // We know linux and seccomp exist, so let's just unwrap. let seccomp_profile = spec.linux().as_ref().unwrap().seccomp().as_ref().unwrap(); - utils::test_in_child_process(|| { + test_utils::test_in_child_process(|| { let _ = prctl::set_no_new_privileges(true); initialize_seccomp(seccomp_profile)?; @@ -469,7 +469,7 @@ mod tests { .architectures(vec![Arch::ScmpArchNative]) .syscalls(vec![syscall]) .build()?; - utils::test_in_child_process(|| { + test_utils::test_in_child_process(|| { let _ = prctl::set_no_new_privileges(true); let fd = initialize_seccomp(&seccomp_profile)?; if fd.is_none() { diff --git a/src/utils.rs b/src/utils.rs index 403c63a4d..29d532d0f 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -2,12 +2,9 @@ use anyhow::Context; use anyhow::{bail, Result}; -use ipc_channel::ipc; use nix::sys::stat::Mode; use nix::sys::statfs; -use nix::sys::wait; use nix::unistd; -use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::ffi::CString; use std::fs::{self, DirBuilder, File}; @@ -218,42 +215,51 @@ pub fn create_temp_dir(test_name: &str) -> Result { Ok(dir) } -#[derive(Debug, Serialize, Deserialize)] -struct TestResult { - success: bool, - message: String, -} +#[cfg(test)] +pub(crate) mod test_utils { + use anyhow::Context; + use anyhow::{bail, Result}; + use ipc_channel::ipc; + use nix::sys::wait; + use serde::{Deserialize, Serialize}; + + #[derive(Debug, Serialize, Deserialize)] + struct TestResult { + success: bool, + message: String, + } -pub fn test_in_child_process Result<()>>(cb: F) -> Result<()> { - let (sender, receiver) = ipc::channel::()?; - match unsafe { nix::unistd::fork()? } { - nix::unistd::ForkResult::Parent { child } => { - let res = receiver.recv().unwrap(); - wait::waitpid(child, None)?; + pub fn test_in_child_process Result<()>>(cb: F) -> Result<()> { + let (sender, receiver) = ipc::channel::()?; + match unsafe { nix::unistd::fork()? } { + nix::unistd::ForkResult::Parent { child } => { + let res = receiver.recv().unwrap(); + wait::waitpid(child, None)?; - if !res.success { - bail!("child process failed: {}", res.message); + if !res.success { + bail!("child process failed: {}", res.message); + } } - } - nix::unistd::ForkResult::Child => { - let test_result = match cb() { - Ok(_) => TestResult { - success: true, - message: String::new(), - }, - Err(err) => TestResult { - success: false, - message: err.to_string(), - }, - }; - sender - .send(test_result) - .context("failed to send from the child process")?; - std::process::exit(0); - } - }; + nix::unistd::ForkResult::Child => { + let test_result = match cb() { + Ok(_) => TestResult { + success: true, + message: String::new(), + }, + Err(err) => TestResult { + success: false, + message: err.to_string(), + }, + }; + sender + .send(test_result) + .context("failed to send from the child process")?; + std::process::exit(0); + } + }; - Ok(()) + Ok(()) + } } #[cfg(test)]