uucore: selinux: Use of_path instead of open+of_file

Opening a pipe may just hang forever, and is not needed to get
selinux context.

Also, pass around follow_symbolic_links parameter from stat to of_path.
This commit is contained in:
Nicolas Boichat
2025-07-28 15:08:05 +08:00
parent b4c6ad1b33
commit 8752c0c098
2 changed files with 20 additions and 14 deletions
+9 -3
View File
@@ -920,6 +920,7 @@ impl Stater {
ret
}
#[allow(clippy::too_many_arguments)]
fn process_token_files(
&self,
t: &Token,
@@ -928,6 +929,7 @@ impl Stater {
file: &OsString,
file_type: &FileType,
from_user: bool,
_follow_symbolic_links: bool,
) -> Result<(), i32> {
match *t {
Token::Byte(byte) => write_raw_byte(byte),
@@ -956,8 +958,10 @@ impl Stater {
#[cfg(feature = "selinux")]
{
if uucore::selinux::is_selinux_enabled() {
match uucore::selinux::get_selinux_security_context(Path::new(file))
{
match uucore::selinux::get_selinux_security_context(
Path::new(file),
_follow_symbolic_links,
) {
Ok(ctx) => OutputType::Str(ctx),
Err(_) => OutputType::Str(get_message(
"stat-selinux-failed-get-context",
@@ -1113,7 +1117,8 @@ impl Stater {
}
}
} else {
let result = if self.follow || stdin_is_fifo && display_name == "-" {
let follow_symbolic_links = self.follow || stdin_is_fifo && display_name == "-";
let result = if follow_symbolic_links {
fs::metadata(&file)
} else {
fs::symlink_metadata(&file)
@@ -1137,6 +1142,7 @@ impl Stater {
&file,
&file_type,
self.from_user,
follow_symbolic_links,
) {
return code;
}
+11 -11
View File
@@ -182,7 +182,7 @@ pub fn set_selinux_security_context(
/// use uucore::selinux::{get_selinux_security_context, SeLinuxError};
///
/// // Get the SELinux context for a file
/// match get_selinux_security_context(Path::new("/path/to/file")) {
/// match get_selinux_security_context(Path::new("/path/to/file"), false) {
/// Ok(context) => {
/// if context.is_empty() {
/// println!("No SELinux context found for the file");
@@ -197,16 +197,16 @@ pub fn set_selinux_security_context(
/// Err(SeLinuxError::ContextSetFailure(ctx, e)) => println!("Failed to set context '{ctx}': {e}"),
/// }
/// ```
pub fn get_selinux_security_context(path: &Path) -> Result<String, SeLinuxError> {
pub fn get_selinux_security_context(
path: &Path,
follow_symbolic_links: bool,
) -> Result<String, SeLinuxError> {
if !is_selinux_enabled() {
return Err(SeLinuxError::SELinuxNotEnabled);
}
let f = std::fs::File::open(path)
.map_err(|e| SeLinuxError::FileOpenFailure(selinux_error_description(&e)))?;
// Get the security context of the file
let context = match SecurityContext::of_file(&f, false) {
let context = match SecurityContext::of_path(path, follow_symbolic_links, false) {
Ok(Some(ctx)) => ctx,
Ok(None) => return Ok(String::new()), // No context found, return empty string
Err(e) => {
@@ -317,7 +317,7 @@ pub fn preserve_security_context(from_path: &Path, to_path: &Path) -> Result<(),
}
// Get context from the source path
let context = get_selinux_security_context(from_path)?;
let context = get_selinux_security_context(from_path, false)?;
// If no context was found, just return success (nothing to preserve)
if context.is_empty() {
@@ -357,7 +357,7 @@ mod tests {
default_result.err()
);
let context = get_selinux_security_context(path).expect("Failed to get context");
let context = get_selinux_security_context(path, false).expect("Failed to get context");
assert!(
!context.is_empty(),
"Expected non-empty context after setting default context"
@@ -367,7 +367,7 @@ mod tests {
let explicit_result = set_selinux_security_context(path, Some(&test_context));
if explicit_result.is_ok() {
let new_context = get_selinux_security_context(path)
let new_context = get_selinux_security_context(path, false)
.expect("Failed to get context after setting explicit context");
assert!(
@@ -420,7 +420,7 @@ mod tests {
}
std::fs::write(path, b"test content").expect("Failed to write to tempfile");
let result = get_selinux_security_context(path);
let result = get_selinux_security_context(path, false);
if result.is_ok() {
let context = result.unwrap();
@@ -484,7 +484,7 @@ mod tests {
println!("test skipped: Kernel has no support for SElinux context");
return;
}
let result = get_selinux_security_context(path);
let result = get_selinux_security_context(path, false);
assert!(result.is_err());
}