diff options
author | Alan Somers <asomers@gmail.com> | 2019-05-26 18:07:52 -0600 |
---|---|---|
committer | Alan Somers <asomers@gmail.com> | 2019-06-06 08:51:54 -0600 |
commit | d39bdbdd9cbe6bb5c782c8ea14932ec62c272764 (patch) | |
tree | 4bb4d8c2f05647568d4b466f8e8dd3eed8ea3c23 | |
parent | 913f8f4748a902842e84f23e00adcddeead4a7a9 (diff) | |
download | nix-d39bdbdd9cbe6bb5c782c8ea14932ec62c272764.zip |
Fix kmod tests on in Linux containers
It's not sufficient to check for root privileges, because a
containerized process may have root's euid but still lack important
capabilities. Fix these tests by checking for the CAP_SYS_MOD
capability.
-rw-r--r-- | test/sys/test_sockopt.rs | 10 | ||||
-rw-r--r-- | test/test.rs | 18 | ||||
-rw-r--r-- | test/test_kmod/mod.rs | 14 |
3 files changed, 25 insertions, 17 deletions
diff --git a/test/sys/test_sockopt.rs b/test/sys/test_sockopt.rs index 5dcdfc02..c4860c0d 100644 --- a/test/sys/test_sockopt.rs +++ b/test/sys/test_sockopt.rs @@ -4,17 +4,9 @@ use nix::sys::socket::{socket, sockopt, getsockopt, setsockopt, AddressFamily, S #[cfg(target_os = "linux")] #[test] fn is_so_mark_functional() { - use ::caps::{Capability, CapSet, has_cap}; - use ::std::io::{self, Write}; use nix::sys::socket::sockopt; - if !has_cap(None, CapSet::Effective, Capability::CAP_NET_ADMIN).unwrap() { - let stderr = io::stderr(); - let mut handle = stderr.lock(); - writeln!(handle, "SO_MARK requires CAP_NET_ADMIN. Skipping test.") - .unwrap(); - return; - } + require_capability!(CAP_NET_ADMIN); let s = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(), None).unwrap(); setsockopt(s, sockopt::Mark, &1337).unwrap(); diff --git a/test/test.rs b/test/test.rs index c7b9c013..0a3d3b74 100644 --- a/test/test.rs +++ b/test/test.rs @@ -1,5 +1,5 @@ extern crate bytes; -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "android", target_os = "linux"))] extern crate caps; #[macro_use] extern crate cfg_if; @@ -11,6 +11,22 @@ extern crate libc; extern crate rand; extern crate tempfile; +#[cfg(any(target_os = "android", target_os = "linux"))] +macro_rules! require_capability { + ($capname:ident) => { + use ::caps::{Capability, CapSet, has_cap}; + use ::std::io::{self, Write}; + + if !has_cap(None, CapSet::Effective, Capability::$capname).unwrap() { + let stderr = io::stderr(); + let mut handle = stderr.lock(); + writeln!(handle, "Insufficient capabilities. Skipping test.") + .unwrap(); + return; + } + } +} + macro_rules! skip_if_not_root { ($name:expr) => { use nix::unistd::Uid; diff --git a/test/test_kmod/mod.rs b/test/test_kmod/mod.rs index e0cb0df5..86558d1b 100644 --- a/test/test_kmod/mod.rs +++ b/test/test_kmod/mod.rs @@ -40,7 +40,7 @@ use std::io::Read; #[test] fn test_finit_and_delete_module() { - skip_if_not_root!("test_finit_module"); + require_capability!(CAP_SYS_MODULE); let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); @@ -56,7 +56,7 @@ fn test_finit_and_delete_module() { #[test] fn test_finit_and_delete_modul_with_params() { - skip_if_not_root!("test_finit_module_with_params"); + require_capability!(CAP_SYS_MODULE); let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); @@ -75,7 +75,7 @@ fn test_finit_and_delete_modul_with_params() { #[test] fn test_init_and_delete_module() { - skip_if_not_root!("test_init_module"); + require_capability!(CAP_SYS_MODULE); let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); @@ -93,7 +93,7 @@ fn test_init_and_delete_module() { #[test] fn test_init_and_delete_module_with_params() { - skip_if_not_root!("test_init_module"); + require_capability!(CAP_SYS_MODULE); let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); @@ -112,7 +112,7 @@ fn test_init_and_delete_module_with_params() { #[test] fn test_finit_module_invalid() { - skip_if_not_root!("test_finit_module_invalid"); + require_capability!(CAP_SYS_MODULE); let kmod_path = "/dev/zero"; @@ -124,7 +124,7 @@ fn test_finit_module_invalid() { #[test] fn test_finit_module_twice_and_delete_module() { - skip_if_not_root!("test_finit_module_twice_and_delete_module"); + require_capability!(CAP_SYS_MODULE); let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); @@ -144,7 +144,7 @@ fn test_finit_module_twice_and_delete_module() { #[test] fn test_delete_module_not_loaded() { - skip_if_not_root!("test_delete_module_not_loaded"); + require_capability!(CAP_SYS_MODULE); let result = delete_module(&CString::new("hello").unwrap(), DeleteModuleFlags::empty()); |