Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add test process user #2978

Merged
merged 23 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions tests/contest/contest/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use crate::tests::linux_ns_itype::get_ns_itype_tests;
use crate::tests::mounts_recursive::get_mounts_recursive_test;
use crate::tests::no_pivot::get_no_pivot_test;
use crate::tests::pidfile::get_pidfile_test;
use crate::tests::process_user::get_process_user_test;
use crate::tests::readonly_paths::get_ro_paths_test;
use crate::tests::scheduler::get_scheduler_test;
use crate::tests::seccomp::get_seccomp_test;
Expand Down Expand Up @@ -114,6 +115,7 @@ fn main() -> Result<()> {
let scheduler = get_scheduler_test();
let io_priority_test = get_io_priority_test();
let devices = get_devices_test();
let process_user = get_process_user_test();
let no_pivot = get_no_pivot_test();

tm.add_test_group(Box::new(cl));
Expand All @@ -138,6 +140,7 @@ fn main() -> Result<()> {
tm.add_test_group(Box::new(sysctl));
tm.add_test_group(Box::new(scheduler));
tm.add_test_group(Box::new(devices));
tm.add_test_group(Box::new(process_user));
tm.add_test_group(Box::new(no_pivot));

tm.add_test_group(Box::new(io_priority_test));
Expand Down
1 change: 1 addition & 0 deletions tests/contest/contest/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub mod linux_ns_itype;
pub mod mounts_recursive;
pub mod no_pivot;
pub mod pidfile;
pub mod process_user;
pub mod readonly_paths;
pub mod scheduler;
pub mod seccomp;
Expand Down
2 changes: 2 additions & 0 deletions tests/contest/contest/src/tests/process_user/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
mod process_user;

Check failure on line 1 in tests/contest/contest/src/tests/process_user/mod.rs

View workflow job for this annotation

GitHub Actions / check (x86_64, gnu)

module has the same name as its containing module

Check failure on line 1 in tests/contest/contest/src/tests/process_user/mod.rs

View workflow job for this annotation

GitHub Actions / check (x86_64, musl)

module has the same name as its containing module

Check failure on line 1 in tests/contest/contest/src/tests/process_user/mod.rs

View workflow job for this annotation

GitHub Actions / check (aarch64, gnu)

module has the same name as its containing module

Check failure on line 1 in tests/contest/contest/src/tests/process_user/mod.rs

View workflow job for this annotation

GitHub Actions / check (aarch64, musl)

module has the same name as its containing module
pub use process_user::get_process_user_test;
38 changes: 38 additions & 0 deletions tests/contest/contest/src/tests/process_user/process_user.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use anyhow::{Context, Ok, Result};
use oci_spec::runtime::{ProcessBuilder, Spec, SpecBuilder, UserBuilder};
use test_framework::{test_result, Test, TestGroup, TestResult};

use crate::utils::test_inside_container;

fn create_spec() -> Result<Spec> {
let user = UserBuilder::default()
.uid(10u32)
.gid(10u32)
.additional_gids(vec![5u32])
.umask(0o02u32)
.build()?;

let spec = SpecBuilder::default()
.process(
ProcessBuilder::default()
.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
}
1 change: 1 addition & 0 deletions tests/contest/runtimetest/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ fn main() {
"io_priority_class_be" => tests::test_io_priority_class(&spec, IoprioClassBe),
"io_priority_class_idle" => tests::test_io_priority_class(&spec, IoprioClassIdle),
"devices" => tests::validate_devices(&spec),
"process_user" => tests::validate_process_user(&spec),
"no_pivot" => tests::validate_rootfs(),
_ => eprintln!("error due to unexpected execute test name: {execute_test}"),
}
Expand Down
39 changes: 39 additions & 0 deletions tests/contest/runtimetest/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::os::unix::fs::{FileTypeExt, PermissionsExt};
use std::path::Path;

use anyhow::{bail, Result};
use libc::{getgid, getuid};
use nix::errno::Errno;
use nix::libc;
use nix::sys::utsname;
Expand Down Expand Up @@ -546,6 +547,44 @@ 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 uid = unsafe { getuid() };
let gid = unsafe { getgid() };
let current_umask = unsafe { libc::umask(0) };
unsafe { libc::umask(current_umask) };

if process.user().uid().ne(&uid) {
eprintln!(
"error due to uid want {}, got {}",
process.user().uid(),
uid
)
}

if process.user().gid().ne(&gid) {
eprintln!(
"error due to gid want {}, got {}",
process.user().gid(),
gid
)
}

if let Err(e) = utils::test_additional_gids(process.user().additional_gids().as_ref().unwrap())
{
eprintln!("error additional gids {e}");
}

if process.user().umask().unwrap().ne(&current_umask) {
eprintln!(
"error due to gid want {}, got {}",
process.user().umask().unwrap(),
current_umask
)
}
}

// the validate_rootfs function is used to validate the rootfs of the container is
// as expected. This function is used in the no_pivot test to validate the rootfs
pub fn validate_rootfs() {
Expand Down
35 changes: 35 additions & 0 deletions tests/contest/runtimetest/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::os::unix::prelude::MetadataExt;
use std::path::PathBuf;
use std::process::Command;

use libc::getgroups;
use nix::sys::stat::{stat, SFlag};

fn test_file_read_access(path: &str) -> Result<(), std::io::Error> {
Expand Down Expand Up @@ -471,3 +472,37 @@ pub fn test_mount_rsuid_option(path: &str) -> Result<(), std::io::Error> {
format!("rsuid error {path:?}"),
))
}

pub fn test_additional_gids(gids: &Vec<u32>) -> Result<(), std::io::Error> {
let ngroups = unsafe { getgroups(0, std::ptr::null_mut()) };

if ngroups == -1 {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"error retrieving group count",
));
}

let mut groups: Vec<libc::gid_t> = vec![0; ngroups as usize];
let result = unsafe { getgroups(ngroups, groups.as_mut_ptr()) };

if result == -1 {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"error retrieving group IDs",
));
}

for group in &groups {
for gid in gids {
if group != gid {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
format!("error additional gid want {}, got {}", gid, group),
));
}
}
}

Ok(())
}
Loading