mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-09-09 04:39:17 +00:00
runtime-rs: hypervisor: add SELinux support functions
Implement core SELinux functionality including label parsing, validation, and process label setting to support SELinux enforcement on hypervisor processes. Fixes #9866 Signed-off-by: Caspian443 <scrisis843@gmail.com>
This commit is contained in:
@@ -18,6 +18,7 @@ pub mod dragonball;
|
|||||||
pub mod firecracker;
|
pub mod firecracker;
|
||||||
mod kernel_param;
|
mod kernel_param;
|
||||||
pub mod qemu;
|
pub mod qemu;
|
||||||
|
pub mod selinux;
|
||||||
pub mod remote;
|
pub mod remote;
|
||||||
pub use kernel_param::Param;
|
pub use kernel_param::Param;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
71
src/runtime-rs/crates/hypervisor/src/selinux.rs
Normal file
71
src/runtime-rs/crates/hypervisor/src/selinux.rs
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
// Copyright 2024 The Kata Containers community
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
use std::fs::{self, OpenOptions};
|
||||||
|
use std::io::prelude::*;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use anyhow::{Context, Result};
|
||||||
|
use nix::unistd::gettid;
|
||||||
|
|
||||||
|
/// Check if SELinux is enabled on the system
|
||||||
|
pub fn is_selinux_enabled() -> bool {
|
||||||
|
let buf = match fs::read_to_string("/proc/mounts") {
|
||||||
|
Ok(content) => content,
|
||||||
|
Err(_) => return false,
|
||||||
|
};
|
||||||
|
buf.contains("selinuxfs")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_exec_label(label: &str) -> Result<()> {
|
||||||
|
let mut attr_path = Path::new("/proc/thread-self/attr/exec").to_path_buf();
|
||||||
|
if !attr_path.exists() {
|
||||||
|
// Fall back to the old convention
|
||||||
|
attr_path = Path::new("/proc/self/task")
|
||||||
|
.join(gettid().to_string())
|
||||||
|
.join("attr/exec")
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut file = OpenOptions::new()
|
||||||
|
.write(true)
|
||||||
|
.truncate(true)
|
||||||
|
.open(attr_path)?;
|
||||||
|
file.write_all(label.as_bytes())
|
||||||
|
.with_context(|| "failed to apply SELinux label")?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
const TEST_LABEL: &str = "system_u:system_r:unconfined_t:s0";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_is_selinux_enabled() {
|
||||||
|
let str = fs::read_to_string("/proc/mounts").unwrap();
|
||||||
|
let expected = str.contains("selinuxfs");
|
||||||
|
assert_eq!(is_selinux_enabled(), expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_set_exec_label() {
|
||||||
|
let ret = set_exec_label(TEST_LABEL);
|
||||||
|
if is_selinux_enabled() {
|
||||||
|
assert!(ret.is_ok(), "Expecting Ok, Got {:?}", ret);
|
||||||
|
// 检查 label 是否被正确设置
|
||||||
|
let mut attr_path = std::path::Path::new("/proc/thread-self/attr/exec").to_path_buf();
|
||||||
|
if !attr_path.exists() {
|
||||||
|
attr_path = std::path::Path::new("/proc/self/task")
|
||||||
|
.join(nix::unistd::gettid().to_string())
|
||||||
|
.join("attr/exec");
|
||||||
|
}
|
||||||
|
let label = std::fs::read_to_string(attr_path).unwrap();
|
||||||
|
assert_eq!(label.trim_end_matches('\0'), TEST_LABEL);
|
||||||
|
} else {
|
||||||
|
assert!(ret.is_err(), "Expecting error, Got {:?}", ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user