Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/uucore/src/lib/features/selinux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,9 @@ impl FsCreateContext {
SeLinuxError::ContextRetrievalFailure(selinux_error_description(&e))
})?;

let path = absolute_for_policy_lookup(path);
let default_context =
match labeler.look_up_by_path(path, mode.and_then(selinux::FileAccessMode::new)) {
match labeler.look_up_by_path(&path, mode.and_then(selinux::FileAccessMode::new)) {
Ok(context) => context,
Err(e) if is_ignorable_context_error(&e) => {
return Ok(Self {
Expand Down
56 changes: 56 additions & 0 deletions tests/by-util/test_mkdir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,62 @@ fn test_selinux_invalid() {
assert!(!at.dir_exists(dest));
}

// -Z looks the name up in the policy, which lists absolute names only: a relative
// name must get the same label as the absolute one.
#[test]
#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))]
fn test_selinux_default_context_relative_name() {
Comment thread
abendrothj marked this conversation as resolved.
use uucore::selinux::{
get_selinux_security_context, is_selinux_enabled, set_selinux_security_context,
};
use uutests::util::AtPath;

if !is_selinux_enabled() {
println!("Skipping SELinux test: SELinux is not enabled");
return;
}
// The policy has no default under /tmp, so both names would inherit there;
// target/tmp is usually under $HOME, which has one.
let dir = tempfile::tempdir_in(env!("CARGO_TARGET_TMPDIR")).unwrap();
let at = AtPath::new(dir.path());
let scene = TestScenario::new(util_name!());
// A type the policy won't hand out here, so a missed lookup shows as inheritance.
Comment thread
abendrothj marked this conversation as resolved.
at.mkdir("parent");
let ctx = String::from("root:object_r:etc_t:s0");
if set_selinux_security_context(&at.plus("parent"), Some(&ctx)).is_err() {
println!("Skipping SELinux test: cannot set a context on the fixture");
return;
}
let type_of = |p: &str| {
let ctx = get_selinux_security_context(&at.plus(p), false).unwrap();
ctx.split(':').nth(2).unwrap().to_owned()
};

scene
.ucmd()
.args(&["-Z", &at.plus_as_string("parent/absolute")])
.succeeds();
let expected = type_of("parent/absolute");
if expected == "etc_t" {
println!("Skipping SELinux test: the policy has no default for {dir:?}");
return;
}
scene
.ucmd()
.current_dir(dir.path())
.args(&["-Z", "parent/relative"])
.succeeds();
scene
.ucmd()
.current_dir(dir.path())
.args(&["-p", "-Z", "parent/new/relative"])
.succeeds();

for name in ["parent/relative", "parent/new", "parent/new/relative"] {
assert_eq!(type_of(name), expected, "{name}");
}
}

#[test]
fn test_mkdir_deep_nesting() {
// Regression test for stack overflow with deeply nested directories.
Expand Down
48 changes: 48 additions & 0 deletions tests/by-util/test_mkfifo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,54 @@ fn test_mkfifo_selinux_invalid() {
}
}

// -Z looks the name up in the policy, which lists absolute names only: a relative
// name must get the same label as the absolute one.
#[test]
#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))]
fn test_mkfifo_selinux_default_context_relative_name() {
use uucore::selinux::{
get_selinux_security_context, is_selinux_enabled, set_selinux_security_context,
};
use uutests::util::AtPath;

if !is_selinux_enabled() {
println!("Skipping SELinux test: SELinux is not enabled");
return;
}
// The policy has no default under /tmp, so both names would inherit there;
// target/tmp is usually under $HOME, which has one.
let dir = tempfile::tempdir_in(env!("CARGO_TARGET_TMPDIR")).unwrap();
let at = AtPath::new(dir.path());
let scene = TestScenario::new(util_name!());
// A type the policy won't hand out here, so a missed lookup shows as inheritance.
at.mkdir("parent");
let ctx = String::from("root:object_r:etc_t:s0");
if set_selinux_security_context(&at.plus("parent"), Some(&ctx)).is_err() {
println!("Skipping SELinux test: cannot set a context on the fixture");
return;
}
let type_of = |p: &str| {
let ctx = get_selinux_security_context(&at.plus(p), false).unwrap();
ctx.split(':').nth(2).unwrap().to_owned()
};

scene
.ucmd()
.args(&["-Z", &at.plus_as_string("parent/absolute")])
.succeeds();
let expected = type_of("parent/absolute");
if expected == "etc_t" {
println!("Skipping SELinux test: the policy has no default for {dir:?}");
return;
}
scene
.ucmd()
.current_dir(dir.path())
.args(&["-Z", "parent/relative"])
.succeeds();
assert_eq!(type_of("parent/relative"), expected);
}

#[test]
fn test_mkfifo_permission_unchanged_when_failed() {
use uucore::fs::display_permissions;
Expand Down
Loading