mirror of
https://github.com/containers/youki
synced 2024-11-22 17:02:00 +01:00
Add e2e test for process user (#2978)
* add-test-process-user Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com> * fix format Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com> * fix error Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com> * fix err and format Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com> * fix err to use UserBuilder Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com> * fix format err Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com> * remove unnecessary return Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com> * rename module name Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com> * fix unsafe code to use nix Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com> * fix err to use nix Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com> * fix format err Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com> * update fn validate_additional_gids to check group ids length Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com> * set additional_gids to random number Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com> * set umask value to variables Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com> * fix format err Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com> * change random number range Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com> * change err msg to use bail Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com> * nit: update error message in case of test failure Signed-off-by: Yashodhan Joshi <yjdoc2@gmail.com> * fix: make sure random gid values are unique Signed-off-by: Yashodhan Joshi <yjdoc2@gmail.com> --------- Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com> Signed-off-by: Yashodhan Joshi <yjdoc2@gmail.com> Co-authored-by: Yashodhan Joshi <yjdoc2@gmail.com>
This commit is contained in:
parent
87befd9386
commit
d5d5fadf99
@ -22,6 +22,7 @@ use crate::tests::mounts_recursive::get_mounts_recursive_test;
|
|||||||
use crate::tests::no_pivot::get_no_pivot_test;
|
use crate::tests::no_pivot::get_no_pivot_test;
|
||||||
use crate::tests::pidfile::get_pidfile_test;
|
use crate::tests::pidfile::get_pidfile_test;
|
||||||
use crate::tests::process_rlimits::get_process_rlimits_test;
|
use crate::tests::process_rlimits::get_process_rlimits_test;
|
||||||
|
use crate::tests::process_user::get_process_user_test;
|
||||||
use crate::tests::readonly_paths::get_ro_paths_test;
|
use crate::tests::readonly_paths::get_ro_paths_test;
|
||||||
use crate::tests::scheduler::get_scheduler_test;
|
use crate::tests::scheduler::get_scheduler_test;
|
||||||
use crate::tests::seccomp::get_seccomp_test;
|
use crate::tests::seccomp::get_seccomp_test;
|
||||||
@ -115,6 +116,7 @@ fn main() -> Result<()> {
|
|||||||
let scheduler = get_scheduler_test();
|
let scheduler = get_scheduler_test();
|
||||||
let io_priority_test = get_io_priority_test();
|
let io_priority_test = get_io_priority_test();
|
||||||
let devices = get_devices_test();
|
let devices = get_devices_test();
|
||||||
|
let process_user = get_process_user_test();
|
||||||
let process_rlimtis = get_process_rlimits_test();
|
let process_rlimtis = get_process_rlimits_test();
|
||||||
let no_pivot = get_no_pivot_test();
|
let no_pivot = get_no_pivot_test();
|
||||||
|
|
||||||
@ -140,6 +142,7 @@ fn main() -> Result<()> {
|
|||||||
tm.add_test_group(Box::new(sysctl));
|
tm.add_test_group(Box::new(sysctl));
|
||||||
tm.add_test_group(Box::new(scheduler));
|
tm.add_test_group(Box::new(scheduler));
|
||||||
tm.add_test_group(Box::new(devices));
|
tm.add_test_group(Box::new(devices));
|
||||||
|
tm.add_test_group(Box::new(process_user));
|
||||||
tm.add_test_group(Box::new(process_rlimtis));
|
tm.add_test_group(Box::new(process_rlimtis));
|
||||||
tm.add_test_group(Box::new(no_pivot));
|
tm.add_test_group(Box::new(no_pivot));
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ pub mod mounts_recursive;
|
|||||||
pub mod no_pivot;
|
pub mod no_pivot;
|
||||||
pub mod pidfile;
|
pub mod pidfile;
|
||||||
pub mod process_rlimits;
|
pub mod process_rlimits;
|
||||||
|
pub mod process_user;
|
||||||
pub mod readonly_paths;
|
pub mod readonly_paths;
|
||||||
pub mod scheduler;
|
pub mod scheduler;
|
||||||
pub mod seccomp;
|
pub mod seccomp;
|
||||||
|
2
tests/contest/contest/src/tests/process_user/mod.rs
Normal file
2
tests/contest/contest/src/tests/process_user/mod.rs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
mod process_user_test;
|
||||||
|
pub use process_user_test::get_process_user_test;
|
@ -0,0 +1,56 @@
|
|||||||
|
use anyhow::{Context, Ok, Result};
|
||||||
|
use oci_spec::runtime::{ProcessBuilder, Spec, SpecBuilder, UserBuilder};
|
||||||
|
use rand::Rng;
|
||||||
|
use test_framework::{test_result, Test, TestGroup, TestResult};
|
||||||
|
|
||||||
|
use crate::utils::test_inside_container;
|
||||||
|
|
||||||
|
// Generates a Vec<u32> with a random number of elements (between 5 and 15),
|
||||||
|
// where each element is a random u32 value between 0 and 65535.
|
||||||
|
fn generate_unique_random_vec() -> Vec<u32> {
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
let vec_size = rng.gen_range(5..=10);
|
||||||
|
let mut ret = Vec::new();
|
||||||
|
while ret.len() < vec_size {
|
||||||
|
let rand = rng.gen_range(100..=200);
|
||||||
|
if !ret.contains(&rand) {
|
||||||
|
ret.push(rand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_spec() -> Result<Spec> {
|
||||||
|
let umask = 0o002;
|
||||||
|
let user = UserBuilder::default()
|
||||||
|
.uid(10u32)
|
||||||
|
.gid(10u32)
|
||||||
|
.additional_gids(generate_unique_random_vec())
|
||||||
|
.umask(umask as u32)
|
||||||
|
.build()?;
|
||||||
|
|
||||||
|
let spec = SpecBuilder::default()
|
||||||
|
.process(
|
||||||
|
ProcessBuilder::default()
|
||||||
|
.args(vec!["runtimetest".to_string(), "process_user".to_string()])
|
||||||
|
.user(user)
|
||||||
|
.build()
|
||||||
|
.expect("error in creating process config"),
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
.context("failed to build spec")?;
|
||||||
|
Ok(spec)
|
||||||
|
}
|
||||||
|
fn process_user_test() -> TestResult {
|
||||||
|
let spec = test_result!(create_spec());
|
||||||
|
test_inside_container(spec, &|_| Ok(()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_process_user_test() -> TestGroup {
|
||||||
|
let mut process_user_test_group = TestGroup::new("process_user");
|
||||||
|
|
||||||
|
let test = Test::new("process_user_test", Box::new(process_user_test));
|
||||||
|
process_user_test_group.add(vec![Box::new(test)]);
|
||||||
|
|
||||||
|
process_user_test_group
|
||||||
|
}
|
@ -44,6 +44,7 @@ fn main() {
|
|||||||
"io_priority_class_be" => tests::test_io_priority_class(&spec, IoprioClassBe),
|
"io_priority_class_be" => tests::test_io_priority_class(&spec, IoprioClassBe),
|
||||||
"io_priority_class_idle" => tests::test_io_priority_class(&spec, IoprioClassIdle),
|
"io_priority_class_idle" => tests::test_io_priority_class(&spec, IoprioClassIdle),
|
||||||
"devices" => tests::validate_devices(&spec),
|
"devices" => tests::validate_devices(&spec),
|
||||||
|
"process_user" => tests::validate_process_user(&spec),
|
||||||
"process_rlimits" => tests::validate_process_rlimits(&spec),
|
"process_rlimits" => tests::validate_process_rlimits(&spec),
|
||||||
"no_pivot" => tests::validate_rootfs(),
|
"no_pivot" => tests::validate_rootfs(),
|
||||||
_ => eprintln!("error due to unexpected execute test name: {execute_test}"),
|
_ => eprintln!("error due to unexpected execute test name: {execute_test}"),
|
||||||
|
@ -7,8 +7,9 @@ use anyhow::{bail, Result};
|
|||||||
use nix::errno::Errno;
|
use nix::errno::Errno;
|
||||||
use nix::libc;
|
use nix::libc;
|
||||||
use nix::sys::resource::{getrlimit, Resource};
|
use nix::sys::resource::{getrlimit, Resource};
|
||||||
|
use nix::sys::stat::{umask, Mode};
|
||||||
use nix::sys::utsname;
|
use nix::sys::utsname;
|
||||||
use nix::unistd::getcwd;
|
use nix::unistd::{getcwd, getgid, getgroups, getuid, Gid, Uid};
|
||||||
use oci_spec::runtime::IOPriorityClass::{self, IoprioClassBe, IoprioClassIdle, IoprioClassRt};
|
use oci_spec::runtime::IOPriorityClass::{self, IoprioClassBe, IoprioClassIdle, IoprioClassRt};
|
||||||
use oci_spec::runtime::{
|
use oci_spec::runtime::{
|
||||||
LinuxDevice, LinuxDeviceType, LinuxSchedulerPolicy, PosixRlimit, PosixRlimitType, Spec,
|
LinuxDevice, LinuxDeviceType, LinuxSchedulerPolicy, PosixRlimit, PosixRlimitType, Spec,
|
||||||
@ -549,6 +550,65 @@ pub fn test_io_priority_class(spec: &Spec, io_priority_class: IOPriorityClass) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn validate_process_user(spec: &Spec) {
|
||||||
|
let process = spec.process().as_ref().unwrap();
|
||||||
|
let expected_uid = Uid::from(process.user().uid());
|
||||||
|
let expected_gid = Gid::from(process.user().gid());
|
||||||
|
let expected_umask = Mode::from_bits(process.user().umask().unwrap()).unwrap();
|
||||||
|
|
||||||
|
let uid = getuid();
|
||||||
|
let gid = getgid();
|
||||||
|
// The umask function not only gets the current mask, but also has the ability to set a new mask,
|
||||||
|
// so we need to set it back after getting the latest value.
|
||||||
|
let current_umask = umask(nix::sys::stat::Mode::empty());
|
||||||
|
umask(current_umask);
|
||||||
|
|
||||||
|
if expected_uid != uid {
|
||||||
|
eprintln!("error due to uid want {}, got {}", expected_uid, uid)
|
||||||
|
}
|
||||||
|
|
||||||
|
if expected_gid != gid {
|
||||||
|
eprintln!("error due to gid want {}, got {}", expected_gid, gid)
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Err(e) = validate_additional_gids(process.user().additional_gids().as_ref().unwrap()) {
|
||||||
|
eprintln!("error additional gids {e}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if expected_umask != current_umask {
|
||||||
|
eprintln!(
|
||||||
|
"error due to umask want {:?}, got {:?}",
|
||||||
|
expected_umask, current_umask
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate_additional_gids function is used to validate additional groups of user
|
||||||
|
fn validate_additional_gids(expected_gids: &Vec<u32>) -> Result<()> {
|
||||||
|
let current_gids = getgroups().unwrap();
|
||||||
|
|
||||||
|
if expected_gids.len() != current_gids.len() {
|
||||||
|
bail!(
|
||||||
|
"error : additional group mismatch, want {:?}, got {:?}",
|
||||||
|
expected_gids,
|
||||||
|
current_gids
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for gid in expected_gids {
|
||||||
|
if !current_gids.contains(&Gid::from_raw(*gid)) {
|
||||||
|
bail!(
|
||||||
|
"error : additional gid {} is not in current groups, expected {:?}, got {:?}",
|
||||||
|
gid,
|
||||||
|
expected_gids,
|
||||||
|
current_gids
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn validate_process_rlimits(spec: &Spec) {
|
pub fn validate_process_rlimits(spec: &Spec) {
|
||||||
let process = spec.process().as_ref().unwrap();
|
let process = spec.process().as_ref().unwrap();
|
||||||
let spec_rlimits: &Vec<PosixRlimit> = process.rlimits().as_ref().unwrap();
|
let spec_rlimits: &Vec<PosixRlimit> = process.rlimits().as_ref().unwrap();
|
||||||
|
Loading…
Reference in New Issue
Block a user