Merge pull request #10234 from pmores/add-support-for-disabled-guest-selinux

runtime-rs: add support for disabled guest selinux
This commit is contained in:
Fabiano Fidêncio 2024-09-19 15:03:24 +02:00 committed by GitHub
commit e9593b53a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 83 additions and 6 deletions

View File

@ -1133,6 +1133,14 @@ pub struct Hypervisor {
/// Vendor customized runtime configuration.
#[serde(default, flatten)]
pub vendor: HypervisorVendor,
/// Disable applying SELinux on the container process.
#[serde(default = "yes")]
pub disable_guest_selinux: bool,
}
fn yes() -> bool {
true
}
impl Hypervisor {

View File

@ -176,6 +176,10 @@ impl Kernel {
kernel_params.append(&mut KernelParams::from_string(
&config.boot_info.kernel_params,
));
kernel_params.append(&mut KernelParams::from_string(&format!(
"selinux={}",
if config.disable_guest_selinux { 0 } else { 1 }
)));
Ok(Kernel {
path: config.boot_info.kernel.clone(),

View File

@ -71,7 +71,7 @@ impl ShareVirtioFsStandalone {
})
}
fn virtiofsd_args(&self, sock_path: &str) -> Result<Vec<String>> {
fn virtiofsd_args(&self, sock_path: &str, disable_guest_selinux: bool) -> Result<Vec<String>> {
let source_path = get_host_ro_shared_path(&self.config.id);
ensure_dir_exist(&source_path)?;
let shared_dir = source_path
@ -96,12 +96,19 @@ impl ShareVirtioFsStandalone {
args.append(&mut extra_args);
}
if !disable_guest_selinux {
args.push(String::from("--xattr"));
}
Ok(args)
}
async fn setup_virtiofsd(&self, h: &dyn Hypervisor) -> Result<()> {
let sock_path = generate_sock_path(&h.get_jailer_root().await?);
let args = self.virtiofsd_args(&sock_path).context("virtiofsd args")?;
let disable_guest_selinux = h.hypervisor_config().await.disable_guest_selinux;
let args = self
.virtiofsd_args(&sock_path, disable_guest_selinux)
.context("virtiofsd args")?;
let mut cmd = Command::new(&self.config.virtio_fs_daemon);
let child_cmd = cmd.args(&args).stderr(Stdio::piped());

View File

@ -97,7 +97,23 @@ impl Container {
let toml_config = self.resource_manager.config().await;
let config = &self.config;
let sandbox_pidns = is_pid_namespace_enabled(&spec);
amend_spec(&mut spec, toml_config.runtime.disable_guest_seccomp).context("amend spec")?;
let disable_guest_selinux = match toml_config
.hypervisor
.get(&toml_config.runtime.hypervisor_name)
{
Some(hypervisor_config) => hypervisor_config.disable_guest_selinux,
// This shouldn't happen due to how logic in the config crate works
// but we need to handle it anyway so we stick with the default
// value of disable_guest_selinux in configuration.toml which
// is 'true'.
None => true,
};
amend_spec(
&mut spec,
toml_config.runtime.disable_guest_seccomp,
disable_guest_selinux,
)
.context("amend spec")?;
// get mutable root from oci spec
let root = match spec.root_mut() {
@ -564,7 +580,11 @@ impl Container {
}
}
fn amend_spec(spec: &mut oci::Spec, disable_guest_seccomp: bool) -> Result<()> {
fn amend_spec(
spec: &mut oci::Spec,
disable_guest_seccomp: bool,
disable_guest_selinux: bool,
) -> Result<()> {
// Only the StartContainer hook needs to be reserved for execution in the guest
let start_container_hooks = if let Some(hooks) = spec.hooks().as_ref() {
hooks.start_container().clone()
@ -609,6 +629,15 @@ fn amend_spec(spec: &mut oci::Spec, disable_guest_seccomp: bool) -> Result<()> {
linux.set_namespaces(if ns.is_empty() { None } else { Some(ns) });
}
if disable_guest_selinux {
if let Some(ref mut process) = spec.process_mut() {
process.set_selinux_label(None);
}
if let Some(ref mut linux) = spec.linux_mut() {
linux.set_mount_label(None);
}
}
Ok(())
}
@ -645,14 +674,43 @@ mod tests {
assert!(spec.linux().as_ref().unwrap().seccomp().is_some());
// disable_guest_seccomp = false
amend_spec(&mut spec, false).unwrap();
amend_spec(&mut spec, false, false).unwrap();
assert!(spec.linux().as_ref().unwrap().seccomp().is_some());
// disable_guest_seccomp = true
amend_spec(&mut spec, true).unwrap();
amend_spec(&mut spec, true, false).unwrap();
assert!(spec.linux().as_ref().unwrap().seccomp().is_none());
}
#[test]
fn test_amend_spec_disable_guest_selinux() {
let mut spec = oci::SpecBuilder::default()
.process(
oci::ProcessBuilder::default()
.selinux_label("xxx".to_owned())
.build()
.unwrap(),
)
.linux(
oci::LinuxBuilder::default()
.mount_label("yyy".to_owned())
.build()
.unwrap(),
)
.build()
.unwrap();
// disable_guest_selinux = false, selinux labels are left alone
amend_spec(&mut spec, false, false).unwrap();
assert!(spec.process().as_ref().unwrap().selinux_label() == &Some("xxx".to_owned()));
assert!(spec.linux().as_ref().unwrap().mount_label() == &Some("yyy".to_owned()));
// disable_guest_selinux = true, selinux labels are reset
amend_spec(&mut spec, false, true).unwrap();
assert!(spec.process().as_ref().unwrap().selinux_label().is_none());
assert!(spec.linux().as_ref().unwrap().mount_label().is_none());
}
#[test]
fn test_is_pid_namespace_enabled() {
struct TestData<'a> {