Skip to content

Commit

Permalink
fix_xattr
Browse files Browse the repository at this point in the history
Signed-off-by: Hiroyuki Moriya <41197469+Gekko0114@users.noreply.github.com>
  • Loading branch information
Gekko0114 committed Sep 28, 2024
1 parent e0d53a8 commit df77c11
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 29 deletions.
7 changes: 0 additions & 7 deletions experiment/selinux/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion experiment/selinux/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
5 changes: 2 additions & 3 deletions experiment/selinux/src/main.rs
Original file line number Diff line number Diff line change
@@ -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() {
Expand Down Expand Up @@ -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)?;
Expand Down
6 changes: 4 additions & 2 deletions experiment/selinux/src/selinux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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");
}
Expand Down Expand Up @@ -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]),
}
}
}
Expand Down
65 changes: 49 additions & 16 deletions experiment/selinux/src/tools/xattr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,31 +34,55 @@ 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()))
}
},
}
}

// function similar with lsetxattr in golang.org/x/sys/unix repo.
// 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()))
}
},
}
}

Expand Down Expand Up @@ -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");
Expand Down

0 comments on commit df77c11

Please sign in to comment.