From 3bc267902cec28aa20cd059c7848c3e8f0225ed3 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 26 Apr 2025 10:22:13 +0200 Subject: [PATCH 1/4] set_selinux_security_context should return an Error, not String --- src/uucore/src/lib/features/selinux.rs | 86 +++++++++++++++----------- 1 file changed, 51 insertions(+), 35 deletions(-) diff --git a/src/uucore/src/lib/features/selinux.rs b/src/uucore/src/lib/features/selinux.rs index eb5191699..02a30112b 100644 --- a/src/uucore/src/lib/features/selinux.rs +++ b/src/uucore/src/lib/features/selinux.rs @@ -6,22 +6,30 @@ use std::path::Path; use selinux::SecurityContext; +use thiserror::Error; -#[derive(Debug)] -pub enum Error { +#[derive(Debug, Error)] +pub enum SeLinuxError { + #[error("SELinux is not enabled on this system")] SELinuxNotEnabled, + + #[error("Failed to open the file")] FileOpenFailure, + + #[error("Failed to retrieve or set the security context")] ContextRetrievalFailure, + + #[error("Invalid context string or conversion failure")] ContextConversionFailure, } -impl From for i32 { - fn from(error: Error) -> i32 { +impl From for i32 { + fn from(error: SeLinuxError) -> i32 { match error { - Error::SELinuxNotEnabled => 1, - Error::FileOpenFailure => 2, - Error::ContextRetrievalFailure => 3, - Error::ContextConversionFailure => 4, + SeLinuxError::SELinuxNotEnabled => 1, + SeLinuxError::FileOpenFailure => 2, + SeLinuxError::ContextRetrievalFailure => 3, + SeLinuxError::ContextConversionFailure => 4, } } } @@ -76,31 +84,36 @@ pub fn is_selinux_enabled() -> bool { /// eprintln!("Failed to set context: {}", err); /// } /// ``` -pub fn set_selinux_security_context(path: &Path, context: Option<&String>) -> Result<(), String> { +pub fn set_selinux_security_context( + path: &Path, + context: Option<&String>, +) -> Result<(), SeLinuxError> { if !is_selinux_enabled() { - return Err("SELinux is not enabled on this system".to_string()); + return Err(SeLinuxError::SELinuxNotEnabled); } if let Some(ctx_str) = context { // Create a CString from the provided context string let c_context = std::ffi::CString::new(ctx_str.as_str()) - .map_err(|_| "Invalid context string (contains null bytes)".to_string())?; + .map_err(|_| SeLinuxError::ContextConversionFailure)?; // Convert the CString into an SELinux security context let security_context = selinux::OpaqueSecurityContext::from_c_str(&c_context) - .map_err(|e| format!("Failed to create security context: {}", e))?; + .map_err(|_| SeLinuxError::ContextConversionFailure)?; // Set the provided security context on the specified path SecurityContext::from_c_str( - &security_context.to_c_string().map_err(|e| e.to_string())?, + &security_context + .to_c_string() + .map_err(|_| SeLinuxError::ContextConversionFailure)?, false, ) .set_for_path(path, false, false) - .map_err(|e| format!("Failed to set context: {}", e)) + .map_err(|_| SeLinuxError::ContextRetrievalFailure) } else { // If no context provided, set the default SELinux context for the path SecurityContext::set_default_for_path(path) - .map_err(|e| format!("Failed to set default context: {}", e)) + .map_err(|_| SeLinuxError::ContextRetrievalFailure) } } @@ -117,17 +130,18 @@ pub fn set_selinux_security_context(path: &Path, context: Option<&String>) -> Re /// /// * `Ok(String)` - The SELinux context string if successfully retrieved. Returns an empty /// string if no context was found. -/// * `Err(Error)` - An error variant indicating the type of failure: -/// - `Error::SELinuxNotEnabled` - SELinux is not enabled on the system. -/// - `Error::FileOpenFailure` - Failed to open the specified file. -/// - `Error::ContextRetrievalFailure` - Failed to retrieve the security context. -/// - `Error::ContextConversionFailure` - Failed to convert the security context to a string. +/// * `Err(SeLinuxError)` - An error variant indicating the type of failure: +/// - `SeLinuxError::SELinuxNotEnabled` - SELinux is not enabled on the system. +/// - `SeLinuxError::FileOpenFailure` - Failed to open the specified file. +/// - `SeLinuxError::ContextRetrievalFailure` - Failed to retrieve the security context. +/// - `SeLinuxError::ContextConversionFailure` - Failed to convert the security context to a string. +/// - `SeLinuxError::ContextSetFailure` - Failed to set the security context. /// /// # Examples /// /// ``` /// use std::path::Path; -/// use uucore::selinux::{get_selinux_security_context, Error}; +/// 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")) { @@ -138,29 +152,29 @@ pub fn set_selinux_security_context(path: &Path, context: Option<&String>) -> Re /// println!("SELinux context: {}", context); /// } /// }, -/// Err(Error::SELinuxNotEnabled) => println!("SELinux is not enabled on this system"), -/// Err(Error::FileOpenFailure) => println!("Failed to open the file"), -/// Err(Error::ContextRetrievalFailure) => println!("Failed to retrieve the security context"), -/// Err(Error::ContextConversionFailure) => println!("Failed to convert the security context to a string"), +/// Err(SeLinuxError::SELinuxNotEnabled) => println!("SELinux is not enabled on this system"), +/// Err(SeLinuxError::FileOpenFailure) => println!("Failed to open the file"), +/// Err(SeLinuxError::ContextRetrievalFailure) => println!("Failed to retrieve the security context"), +/// Err(SeLinuxError::ContextConversionFailure) => println!("Failed to convert the security context to a string"), /// } /// ``` -pub fn get_selinux_security_context(path: &Path) -> Result { +pub fn get_selinux_security_context(path: &Path) -> Result { if !is_selinux_enabled() { - return Err(Error::SELinuxNotEnabled); + return Err(SeLinuxError::SELinuxNotEnabled); } - let f = std::fs::File::open(path).map_err(|_| Error::FileOpenFailure)?; + let f = std::fs::File::open(path).map_err(|_| SeLinuxError::FileOpenFailure)?; // Get the security context of the file let context = match SecurityContext::of_file(&f, false) { Ok(Some(ctx)) => ctx, Ok(None) => return Ok(String::new()), // No context found, return empty string - Err(_) => return Err(Error::ContextRetrievalFailure), + Err(_) => return Err(SeLinuxError::ContextRetrievalFailure), }; let context_c_string = context .to_c_string() - .map_err(|_| Error::ContextConversionFailure)?; + .map_err(|_| SeLinuxError::ContextConversionFailure)?; if let Some(c_str) = context_c_string { // Convert the C string to a Rust String @@ -249,10 +263,12 @@ mod tests { // Valid error types match err { - Error::SELinuxNotEnabled => assert!(true, "SELinux not supported"), - Error::ContextRetrievalFailure => assert!(true, "Context retrieval failure"), - Error::ContextConversionFailure => assert!(true, "Context conversion failure"), - Error::FileOpenFailure => { + SeLinuxError::SELinuxNotEnabled => assert!(true, "SELinux not supported"), + SeLinuxError::ContextRetrievalFailure => assert!(true, "Context retrieval failure"), + SeLinuxError::ContextConversionFailure => { + assert!(true, "Context conversion failure") + } + SeLinuxError::FileOpenFailure => { panic!("File open failure occurred despite file being created") } } @@ -267,7 +283,7 @@ mod tests { assert!(result.is_err()); assert!( - matches!(result.unwrap_err(), Error::FileOpenFailure), + matches!(result.unwrap_err(), SeLinuxError::FileOpenFailure), "Expected file open error for nonexistent file" ); } From 8d94add3930a91c53e510dfafb2894e66b7d2d94 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 26 Apr 2025 11:10:42 +0200 Subject: [PATCH 2/4] set_selinux_security_context split the ContextRetrievalFailure error in two --- src/uucore/src/lib/features/selinux.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/uucore/src/lib/features/selinux.rs b/src/uucore/src/lib/features/selinux.rs index 02a30112b..eb14eb816 100644 --- a/src/uucore/src/lib/features/selinux.rs +++ b/src/uucore/src/lib/features/selinux.rs @@ -16,9 +16,12 @@ pub enum SeLinuxError { #[error("Failed to open the file")] FileOpenFailure, - #[error("Failed to retrieve or set the security context")] + #[error("Failed to retrieve the security context")] ContextRetrievalFailure, + #[error("Failed to set the security context")] + ContextSetFailure, + #[error("Invalid context string or conversion failure")] ContextConversionFailure, } @@ -29,7 +32,8 @@ impl From for i32 { SeLinuxError::SELinuxNotEnabled => 1, SeLinuxError::FileOpenFailure => 2, SeLinuxError::ContextRetrievalFailure => 3, - SeLinuxError::ContextConversionFailure => 4, + SeLinuxError::ContextSetFailure => 4, + SeLinuxError::ContextConversionFailure => 5, } } } @@ -109,11 +113,10 @@ pub fn set_selinux_security_context( false, ) .set_for_path(path, false, false) - .map_err(|_| SeLinuxError::ContextRetrievalFailure) + .map_err(|_| SeLinuxError::ContextSetFailure) } else { // If no context provided, set the default SELinux context for the path - SecurityContext::set_default_for_path(path) - .map_err(|_| SeLinuxError::ContextRetrievalFailure) + SecurityContext::set_default_for_path(path).map_err(|_| SeLinuxError::ContextSetFailure) } } From 595f56a9e7f08bec88cfe2a30323d2b498b85a22 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 26 Apr 2025 11:16:22 +0200 Subject: [PATCH 3/4] set_selinux_security_context: match GNU's error --- src/uucore/src/lib/features/selinux.rs | 11 ++++++----- tests/by-util/test_mkfifo.rs | 2 +- tests/by-util/test_mknod.rs | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/uucore/src/lib/features/selinux.rs b/src/uucore/src/lib/features/selinux.rs index eb14eb816..7d7fa98eb 100644 --- a/src/uucore/src/lib/features/selinux.rs +++ b/src/uucore/src/lib/features/selinux.rs @@ -19,8 +19,8 @@ pub enum SeLinuxError { #[error("Failed to retrieve the security context")] ContextRetrievalFailure, - #[error("Failed to set the security context")] - ContextSetFailure, + #[error("failed to set default file creation context to {0}")] + ContextSetFailure(String), #[error("Invalid context string or conversion failure")] ContextConversionFailure, @@ -32,7 +32,7 @@ impl From for i32 { SeLinuxError::SELinuxNotEnabled => 1, SeLinuxError::FileOpenFailure => 2, SeLinuxError::ContextRetrievalFailure => 3, - SeLinuxError::ContextSetFailure => 4, + SeLinuxError::ContextSetFailure(_) => 4, SeLinuxError::ContextConversionFailure => 5, } } @@ -113,10 +113,11 @@ pub fn set_selinux_security_context( false, ) .set_for_path(path, false, false) - .map_err(|_| SeLinuxError::ContextSetFailure) + .map_err(|_| SeLinuxError::ContextSetFailure(ctx_str.to_string())) } else { // If no context provided, set the default SELinux context for the path - SecurityContext::set_default_for_path(path).map_err(|_| SeLinuxError::ContextSetFailure) + SecurityContext::set_default_for_path(path) + .map_err(|_| SeLinuxError::ContextSetFailure("".to_string())) } } diff --git a/tests/by-util/test_mkfifo.rs b/tests/by-util/test_mkfifo.rs index c9c62b41f..721b559ae 100644 --- a/tests/by-util/test_mkfifo.rs +++ b/tests/by-util/test_mkfifo.rs @@ -160,7 +160,7 @@ fn test_mkfifo_selinux_invalid() { .arg(arg) .arg(dest) .fails() - .stderr_contains("Failed to"); + .stderr_contains("failed to"); if at.file_exists(dest) { at.remove(dest); } diff --git a/tests/by-util/test_mknod.rs b/tests/by-util/test_mknod.rs index 6d393c2f6..daefe6cda 100644 --- a/tests/by-util/test_mknod.rs +++ b/tests/by-util/test_mknod.rs @@ -187,7 +187,7 @@ fn test_mknod_selinux_invalid() { .arg(dest) .arg("p") .fails() - .stderr_contains("Failed to"); + .stderr_contains("failed to"); if at.file_exists(dest) { at.remove(dest); } From c177362a51d7269f284cea2c6c9bf447a4439432 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 26 Apr 2025 15:21:12 +0200 Subject: [PATCH 4/4] set_selinux_security_context: also display the error from the crate + fix comments from review --- src/uu/mkdir/src/mkdir.rs | 5 +- src/uucore/Cargo.toml | 2 +- src/uucore/src/lib/features/selinux.rs | 197 +++++++++++++++++-------- tests/by-util/test_mkdir.rs | 2 +- 4 files changed, 140 insertions(+), 66 deletions(-) diff --git a/src/uu/mkdir/src/mkdir.rs b/src/uu/mkdir/src/mkdir.rs index 958d3b6f8..adef62eee 100644 --- a/src/uu/mkdir/src/mkdir.rs +++ b/src/uu/mkdir/src/mkdir.rs @@ -298,10 +298,7 @@ fn create_dir(path: &Path, is_parent: bool, config: &Config) -> UResult<()> { if let Err(e) = uucore::selinux::set_selinux_security_context(path, config.context) { let _ = std::fs::remove_dir(path); - return Err(USimpleError::new( - 1, - format!("failed to set SELinux security context: {}", e), - )); + return Err(USimpleError::new(1, e.to_string())); } } diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index acbba4c73..746e24f46 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -114,7 +114,7 @@ proc-info = ["tty", "walkdir"] quoting-style = [] ranges = [] ringbuffer = [] -selinux = ["dep:selinux"] +selinux = ["dep:selinux", "thiserror"] signals = [] sum = [ "digest", diff --git a/src/uucore/src/lib/features/selinux.rs b/src/uucore/src/lib/features/selinux.rs index 7d7fa98eb..18261912c 100644 --- a/src/uucore/src/lib/features/selinux.rs +++ b/src/uucore/src/lib/features/selinux.rs @@ -13,27 +13,27 @@ pub enum SeLinuxError { #[error("SELinux is not enabled on this system")] SELinuxNotEnabled, - #[error("Failed to open the file")] - FileOpenFailure, + #[error("Failed to open the file: {0}")] + FileOpenFailure(String), - #[error("Failed to retrieve the security context")] - ContextRetrievalFailure, + #[error("Failed to retrieve the security context: {0}")] + ContextRetrievalFailure(String), - #[error("failed to set default file creation context to {0}")] - ContextSetFailure(String), + #[error("Failed to set default file creation context to '{0}': {1}")] + ContextSetFailure(String, String), - #[error("Invalid context string or conversion failure")] - ContextConversionFailure, + #[error("Failed to set default file creation context to '{0}': {1}")] + ContextConversionFailure(String, String), } impl From for i32 { fn from(error: SeLinuxError) -> i32 { match error { SeLinuxError::SELinuxNotEnabled => 1, - SeLinuxError::FileOpenFailure => 2, - SeLinuxError::ContextRetrievalFailure => 3, - SeLinuxError::ContextSetFailure(_) => 4, - SeLinuxError::ContextConversionFailure => 5, + SeLinuxError::FileOpenFailure(_) => 2, + SeLinuxError::ContextRetrievalFailure(_) => 3, + SeLinuxError::ContextSetFailure(_, _) => 4, + SeLinuxError::ContextConversionFailure(_, _) => 5, } } } @@ -98,26 +98,29 @@ pub fn set_selinux_security_context( if let Some(ctx_str) = context { // Create a CString from the provided context string - let c_context = std::ffi::CString::new(ctx_str.as_str()) - .map_err(|_| SeLinuxError::ContextConversionFailure)?; + let c_context = std::ffi::CString::new(ctx_str.as_str()).map_err(|e| { + SeLinuxError::ContextConversionFailure(ctx_str.to_string(), e.to_string()) + })?; // Convert the CString into an SELinux security context - let security_context = selinux::OpaqueSecurityContext::from_c_str(&c_context) - .map_err(|_| SeLinuxError::ContextConversionFailure)?; + let security_context = + selinux::OpaqueSecurityContext::from_c_str(&c_context).map_err(|e| { + SeLinuxError::ContextConversionFailure(ctx_str.to_string(), e.to_string()) + })?; // Set the provided security context on the specified path SecurityContext::from_c_str( - &security_context - .to_c_string() - .map_err(|_| SeLinuxError::ContextConversionFailure)?, + &security_context.to_c_string().map_err(|e| { + SeLinuxError::ContextConversionFailure(ctx_str.to_string(), e.to_string()) + })?, false, ) .set_for_path(path, false, false) - .map_err(|_| SeLinuxError::ContextSetFailure(ctx_str.to_string())) + .map_err(|e| SeLinuxError::ContextSetFailure(ctx_str.to_string(), e.to_string())) } else { // If no context provided, set the default SELinux context for the path SecurityContext::set_default_for_path(path) - .map_err(|_| SeLinuxError::ContextSetFailure("".to_string())) + .map_err(|e| SeLinuxError::ContextSetFailure(String::new(), e.to_string())) } } @@ -157,9 +160,10 @@ pub fn set_selinux_security_context( /// } /// }, /// Err(SeLinuxError::SELinuxNotEnabled) => println!("SELinux is not enabled on this system"), -/// Err(SeLinuxError::FileOpenFailure) => println!("Failed to open the file"), -/// Err(SeLinuxError::ContextRetrievalFailure) => println!("Failed to retrieve the security context"), -/// Err(SeLinuxError::ContextConversionFailure) => println!("Failed to convert the security context to a string"), +/// Err(SeLinuxError::FileOpenFailure(e)) => println!("Failed to open the file: {}", e), +/// Err(SeLinuxError::ContextRetrievalFailure(e)) => println!("Failed to retrieve the security context: {}", e), +/// Err(SeLinuxError::ContextConversionFailure(ctx, e)) => println!("Failed to convert context '{}': {}", ctx, e), +/// Err(SeLinuxError::ContextSetFailure(ctx, e)) => println!("Failed to set context '{}': {}", ctx, e), /// } /// ``` pub fn get_selinux_security_context(path: &Path) -> Result { @@ -167,18 +171,18 @@ pub fn get_selinux_security_context(path: &Path) -> Result return Err(SeLinuxError::SELinuxNotEnabled); } - let f = std::fs::File::open(path).map_err(|_| SeLinuxError::FileOpenFailure)?; + let f = std::fs::File::open(path).map_err(|e| SeLinuxError::FileOpenFailure(e.to_string()))?; // Get the security context of the file let context = match SecurityContext::of_file(&f, false) { Ok(Some(ctx)) => ctx, Ok(None) => return Ok(String::new()), // No context found, return empty string - Err(_) => return Err(SeLinuxError::ContextRetrievalFailure), + Err(e) => return Err(SeLinuxError::ContextRetrievalFailure(e.to_string())), }; let context_c_string = context .to_c_string() - .map_err(|_| SeLinuxError::ContextConversionFailure)?; + .map_err(|e| SeLinuxError::ContextConversionFailure(String::new(), e.to_string()))?; if let Some(c_str) = context_c_string { // Convert the C string to a Rust String @@ -198,29 +202,50 @@ mod tests { let tmpfile = NamedTempFile::new().expect("Failed to create tempfile"); let path = tmpfile.path(); - let result = set_selinux_security_context(path, None); + if !is_selinux_enabled() { + let result = set_selinux_security_context(path, None); + assert!(result.is_err(), "Expected error when SELinux is disabled"); + match result.unwrap_err() { + SeLinuxError::SELinuxNotEnabled => { + // This is the expected error when SELinux is not enabled + } + err => panic!("Expected SELinuxNotEnabled error but got: {}", err), + } + return; + } - if result.is_ok() { - // SELinux enabled and successfully set default context - assert!(true, "Successfully set SELinux context"); - } else { - let err = result.unwrap_err(); - let valid_errors = [ - "SELinux is not enabled on this system", - &format!( - "Failed to set default context: selinux_lsetfilecon_default() failed on path '{}'", - path.display() - ), - ]; + let default_result = set_selinux_security_context(path, None); + assert!( + default_result.is_ok(), + "Failed to set default context: {:?}", + default_result.err() + ); + + let context = get_selinux_security_context(path).expect("Failed to get context"); + assert!( + !context.is_empty(), + "Expected non-empty context after setting default context" + ); + + let test_context = String::from("system_u:object_r:tmp_t:s0"); + let explicit_result = set_selinux_security_context(path, Some(&test_context)); + + if explicit_result.is_ok() { + let new_context = get_selinux_security_context(path) + .expect("Failed to get context after setting explicit context"); assert!( - valid_errors.contains(&err.as_str()), - "Unexpected error message: {}", - err + new_context.contains("tmp_t"), + "Expected context to contain 'tmp_t', but got: {}", + new_context + ); + } else { + println!( + "Note: Could not set explicit context {:?}", + explicit_result.err() ); } } - #[test] fn test_invalid_context_string_error() { let tmpfile = NamedTempFile::new().expect("Failed to create tempfile"); @@ -231,10 +256,18 @@ mod tests { let result = set_selinux_security_context(path, Some(&invalid_context)); assert!(result.is_err()); - assert_eq!( - result.unwrap_err(), - "Invalid context string (contains null bytes)" - ); + if let Err(err) = result { + match err { + SeLinuxError::ContextConversionFailure(ctx, msg) => { + assert_eq!(ctx, "invalid\0context"); + assert!( + msg.contains("nul byte"), + "Error message should mention nul byte" + ); + } + _ => panic!("Expected ContextConversionFailure error but got: {}", err), + } + } } #[test] @@ -261,19 +294,56 @@ mod tests { let result = get_selinux_security_context(path); if result.is_ok() { - println!("Retrieved SELinux context: {}", result.unwrap()); + let context = result.unwrap(); + println!("Retrieved SELinux context: {}", context); + + assert!( + is_selinux_enabled(), + "Got a successful context result but SELinux is not enabled" + ); + + if !context.is_empty() { + assert!( + context.contains(':'), + "SELinux context '{}' doesn't match expected format", + context + ); + } } else { let err = result.unwrap_err(); - // Valid error types match err { - SeLinuxError::SELinuxNotEnabled => assert!(true, "SELinux not supported"), - SeLinuxError::ContextRetrievalFailure => assert!(true, "Context retrieval failure"), - SeLinuxError::ContextConversionFailure => { - assert!(true, "Context conversion failure") + SeLinuxError::SELinuxNotEnabled => { + assert!( + !is_selinux_enabled(), + "Got SELinuxNotEnabled error, but is_selinux_enabled() returned true" + ); } - SeLinuxError::FileOpenFailure => { - panic!("File open failure occurred despite file being created") + SeLinuxError::ContextRetrievalFailure(e) => { + assert!( + is_selinux_enabled(), + "Got ContextRetrievalFailure when SELinux is not enabled" + ); + assert!(!e.is_empty(), "Error message should not be empty"); + println!("Context retrieval failure: {}", e); + } + SeLinuxError::ContextConversionFailure(ctx, e) => { + assert!( + is_selinux_enabled(), + "Got ContextConversionFailure when SELinux is not enabled" + ); + assert!(!e.is_empty(), "Error message should not be empty"); + println!("Context conversion failure for '{}': {}", ctx, e); + } + SeLinuxError::ContextSetFailure(ctx, e) => { + assert!(false); + } + SeLinuxError::FileOpenFailure(e) => { + assert!( + Path::new(path).exists(), + "File open failure occurred despite file being created: {}", + e + ); } } } @@ -286,9 +356,16 @@ mod tests { let result = get_selinux_security_context(path); assert!(result.is_err()); - assert!( - matches!(result.unwrap_err(), SeLinuxError::FileOpenFailure), - "Expected file open error for nonexistent file" - ); + if let Err(err) = result { + match err { + SeLinuxError::FileOpenFailure(e) => { + assert!( + e.contains("No such file"), + "Error should mention file not found" + ); + } + _ => panic!("Expected FileOpenFailure error but got: {}", err), + } + } } } diff --git a/tests/by-util/test_mkdir.rs b/tests/by-util/test_mkdir.rs index bfb65590c..589025b37 100644 --- a/tests/by-util/test_mkdir.rs +++ b/tests/by-util/test_mkdir.rs @@ -411,7 +411,7 @@ fn test_selinux_invalid() { .arg(at.plus_as_string(dest)) .fails() .no_stdout() - .stderr_contains("failed to set SELinux security context:"); + .stderr_contains("Failed to set default file creation context to 'testtest':"); // invalid context, so, no directory assert!(!at.dir_exists(dest)); }