diff --git a/experiment/selinux/Cargo.lock b/experiment/selinux/Cargo.lock index 5a515cc41..ca9ba1bd1 100644 --- a/experiment/selinux/Cargo.lock +++ b/experiment/selinux/Cargo.lock @@ -2,12 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "anyhow" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" - [[package]] name = "autocfg" version = "1.3.0" @@ -117,7 +111,6 @@ dependencies = [ name = "selinux" version = "0.1.0" dependencies = [ - "anyhow", "nix", "rustix", "tempfile", diff --git a/experiment/selinux/Cargo.toml b/experiment/selinux/Cargo.toml index 785c7cd75..35107f76a 100644 --- a/experiment/selinux/Cargo.toml +++ b/experiment/selinux/Cargo.toml @@ -12,7 +12,6 @@ autoexamples = true keywords = ["youki", "container", "selinux"] [dependencies] -anyhow = "1.0.86" nix = { version = "0.29.0", features = ["process", "fs", "socket"] } rustix = { version = "0.38.34", features = ["fs"] } tempfile = "3.10.1" diff --git a/experiment/selinux/src/main.rs b/experiment/selinux/src/main.rs index a3a27f8f1..71cde5f69 100644 --- a/experiment/selinux/src/main.rs +++ b/experiment/selinux/src/main.rs @@ -1,10 +1,9 @@ -use anyhow::Result; use selinux::selinux::*; use selinux::selinux_label::*; use std::fs::File; use std::path::Path; -fn main() -> Result<()> { +fn main() -> Result<(), SELinuxError> { let mut selinux_instance: SELinux = SELinux::new(); if selinux_instance.get_enabled() { @@ -32,7 +31,7 @@ fn main() -> Result<()> { } let file_path = Path::new("./test_file.txt"); - let _file = File::create(file_path)?; + let _file = File::create(file_path).map_err(|e| SELinuxError::Run(e.to_string()))?; let selinux_label = SELinuxLabel::try_from("system_u:object_r:public_content_t:s0".to_string())?; SELinux::set_file_label(file_path, selinux_label)?; diff --git a/experiment/selinux/src/selinux.rs b/experiment/selinux/src/selinux.rs index e724cf997..b0f291366 100644 --- a/experiment/selinux/src/selinux.rs +++ b/experiment/selinux/src/selinux.rs @@ -91,6 +91,8 @@ pub enum SELinuxError { GetConfigKey(String), #[error("Invalid format for SELinux label: {0}")] InvalidSELinuxLabel(String), + #[error("Failed to run: {0}")] + Run(String), } pub struct SELinux { @@ -489,7 +491,7 @@ mod tests { fn create_temp_file(content: &[u8], file_name: &str) { let path = Path::new(file_name); - let mut file = File::create(&path).expect("Failed to create file"); + let mut file = File::create(path).expect("Failed to create file"); file.write_all(content).expect("Failed to write to file"); file.sync_all().expect("Failed to sync file"); } @@ -570,7 +572,7 @@ mod tests { let expected = PathBuf::from(expected_array[i]); match SELinux::check_line_include_selinux_fs_mount_point(input) { Some(output) => assert_eq!(expected, output), - None => assert_eq!(succeeded_array[i], false), + None => assert!(!succeeded_array[i]), } } } diff --git a/experiment/selinux/src/tools/xattr.rs b/experiment/selinux/src/tools/xattr.rs index 9d39fbe44..38ab32cfe 100644 --- a/experiment/selinux/src/tools/xattr.rs +++ b/experiment/selinux/src/tools/xattr.rs @@ -34,15 +34,27 @@ where // set_xattr sets extended attributes on a file specified by its path. fn set_xattr(&self, attr: &str, data: &[u8]) -> Result<(), XattrError> { let path = self.as_ref(); - match rfs::setxattr(path, attr, data, rfs::XattrFlags::REPLACE) { - Ok(_) => Ok(()), - Err(e) => { - let errno = e.raw_os_error(); - if errno == libc::EINTR { - return Err(XattrError::EINTR(errno)); + match path.get_xattr(attr) { + Ok(_) => match rfs::setxattr(path, attr, data, rfs::XattrFlags::REPLACE) { + Ok(_) => Ok(()), + Err(e) => { + let errno = e.raw_os_error(); + if errno == libc::EINTR { + return Err(XattrError::EINTR(errno)); + } + Err(XattrError::SetXattr(e.to_string())) } - Err(XattrError::SetXattr(e.to_string())) - } + }, + Err(_) => match rfs::setxattr(path, attr, data, rfs::XattrFlags::CREATE) { + Ok(_) => Ok(()), + Err(e) => { + let errno = e.raw_os_error(); + if errno == libc::EINTR { + return Err(XattrError::EINTR(errno)); + } + Err(XattrError::SetXattr(e.to_string())) + } + }, } } @@ -50,15 +62,27 @@ where // lset_xattr sets extended attributes on a symbolic link. fn lset_xattr(&self, attr: &str, data: &[u8]) -> Result<(), XattrError> { let path = self.as_ref(); - match rfs::lsetxattr(path, attr, data, rfs::XattrFlags::REPLACE) { - Ok(_) => Ok(()), - Err(e) => { - let errno = e.raw_os_error(); - if errno == libc::EINTR { - return Err(XattrError::EINTR(errno)); + match path.lget_xattr(attr) { + Ok(_) => match rfs::lsetxattr(path, attr, data, rfs::XattrFlags::REPLACE) { + Ok(_) => Ok(()), + Err(e) => { + let errno = e.raw_os_error(); + if errno == libc::EINTR { + return Err(XattrError::EINTR(errno)); + } + Err(XattrError::LSetXattr(e.to_string())) } - Err(XattrError::LSetXattr(e.to_string())) - } + }, + Err(_) => match rfs::lsetxattr(path, attr, data, rfs::XattrFlags::CREATE) { + Ok(_) => Ok(()), + Err(e) => { + let errno = e.raw_os_error(); + if errno == libc::EINTR { + return Err(XattrError::EINTR(errno)); + } + Err(XattrError::LSetXattr(e.to_string())) + } + }, } } @@ -128,6 +152,15 @@ mod tests { let temp_file = NamedTempFile::new().expect("Failed to create temp file"); let file_path = temp_file.path(); + // Verify that the first "set_xattr" operation succeeds, which means it doesn't have xattr yet. + file_path + .set_xattr(attr_name, attr_value.as_bytes()) + .expect("Failed to set xattr"); + let actual = file_path.get_xattr(attr_name).expect("Failed to get xattr"); + assert_eq!(actual, attr_value); + + // Verify that the second "set_xattr" operation succeeds, which means it already has xattr. + let attr_value = "system_u:object_r:another_label_t"; file_path .set_xattr(attr_name, attr_value.as_bytes()) .expect("Failed to set xattr");