diff --git a/src/agent/rustjail/src/lib.rs b/src/agent/rustjail/src/lib.rs index c77da3a30..6c14ed8a0 100644 --- a/src/agent/rustjail/src/lib.rs +++ b/src/agent/rustjail/src/lib.rs @@ -580,4 +580,15 @@ mod tests { fn it_works() { assert_eq!(2 + 2, 4); } + + #[allow(unused_macros)] + #[macro_export] + macro_rules! skip_if_not_root { + () => { + if !nix::unistd::Uid::effective().is_root() { + println!("INFO: skipping {} which needs root", module_path!()); + return; + } + }; + } } diff --git a/src/agent/rustjail/src/mount.rs b/src/agent/rustjail/src/mount.rs index 0fa5b9d19..8bc3152da 100644 --- a/src/agent/rustjail/src/mount.rs +++ b/src/agent/rustjail/src/mount.rs @@ -894,6 +894,7 @@ fn readonly_path(path: &str) -> Result<()> { #[cfg(test)] mod tests { use super::*; + use crate::skip_if_not_root; use std::os::unix::io::AsRawFd; use tempfile::tempdir; @@ -1060,4 +1061,66 @@ mod tests { let ret = mask_path("/tmp"); assert!(ret.is_ok(), "Should pass. Got: {:?}", ret); } + + #[test] + fn test_finish_rootfs() { + let stdout_fd = std::io::stdout().as_raw_fd(); + let mut spec = oci::Spec::default(); + + spec.linux = Some(oci::Linux::default()); + spec.linux.as_mut().unwrap().masked_paths = vec!["/tmp".to_string()]; + spec.linux.as_mut().unwrap().readonly_paths = vec!["/tmp".to_string()]; + spec.root = Some(oci::Root { + path: "/tmp".to_string(), + readonly: true, + }); + spec.mounts = vec![oci::Mount { + destination: "/dev".to_string(), + r#type: "bind".to_string(), + source: "/dev".to_string(), + options: vec!["ro".to_string(), "shared".to_string()], + }]; + + let ret = finish_rootfs(stdout_fd, &spec); + assert!(ret.is_ok(), "Should pass. Got: {:?}", ret); + } + + #[test] + fn test_readonly_path() { + let ret = readonly_path("abc"); + assert!(ret.is_err(), "Should fail. Got: {:?}", ret); + + let ret = readonly_path("../../"); + assert!(ret.is_err(), "Should fail. Got: {:?}", ret); + + let ret = readonly_path("/tmp"); + assert!(ret.is_ok(), "Should pass. Got: {:?}", ret); + } + + #[test] + fn test_mknod_dev() { + skip_if_not_root!(); + + let tempdir = tempdir().unwrap(); + + let olddir = unistd::getcwd().unwrap(); + defer!(unistd::chdir(&olddir);); + unistd::chdir(tempdir.path()); + + let dev = oci::LinuxDevice { + path: "/fifo".to_string(), + r#type: "c".to_string(), + major: 0, + minor: 0, + file_mode: Some(0660), + uid: Some(unistd::getuid().as_raw()), + gid: Some(unistd::getgid().as_raw()), + }; + + let ret = mknod_dev(&dev); + assert!(ret.is_ok(), "Should pass. Got: {:?}", ret); + + let ret = stat::stat("fifo"); + assert!(ret.is_ok(), "Should pass. Got: {:?}", ret); + } }