Skip to content

Commit

Permalink
Convert chflags/09.t
Browse files Browse the repository at this point in the history
This test asserts that chflags will fail if securelevel=1 and certain
flags are already set.  Since it requires changing securelevel, we do it
in a jail, using the jail-rs crate.  Since we can't fork in a
multithreaded program, we instead execute /bin/chflags within the jail.

Issue pjd#10
  • Loading branch information
asomers committed Feb 5, 2024
1 parent bf1a04b commit fb297b9
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 6 deletions.
129 changes: 123 additions & 6 deletions rust/Cargo.lock

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

3 changes: 3 additions & 0 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ rev = "20df092bd067908fba23e49120eed7ad62f29108"
git = "https://github.com/nix-rust/nix.git"
features = ["fs", "socket", "mount"]

[target.'cfg(target_os = "freebsd")'.dependencies]
jail = "0.2.0"

[target.'cfg(target_os = "linux")'.dependencies]
caps = "0.5.4"

Expand Down
16 changes: 16 additions & 0 deletions rust/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ pub struct TestContext<'a> {
temp_dir: &'a Path,
features_config: &'a FeaturesConfig,
auth_entries: DummyAuthEntries<'a>,
#[cfg(target_os = "freebsd")]
jail: Option<jail::RunningJail>
}

pub struct SerializedTestContext<'a> {
Expand Down Expand Up @@ -162,6 +164,8 @@ impl<'a> TestContext<'a> {
temp_dir,
features_config: &config.features,
auth_entries: DummyAuthEntries::new(entries),
#[cfg(target_os = "freebsd")]
jail: None
}
}

Expand Down Expand Up @@ -275,6 +279,12 @@ impl<'a> TestContext<'a> {
pub fn nap(&self) {
thread::sleep(self.naptime)
}

/// Set this Context's jail, so it will be destroyed during teardown.
#[cfg(target_os = "freebsd")]
pub fn set_jail(&mut self, jail: jail::RunningJail) {
self.jail = Some(jail)
}
}

// We implement Drop to circumvent the errors which arise from unlinking a directory for which
Expand Down Expand Up @@ -325,6 +335,12 @@ impl<'a> Drop for TestContext<'a> {
let _ = lchflags(entry.path(), FileFlag::empty());
}
}

// Shut down any jails
#[cfg(target_os = "freebsd")]
if let Some(jail) = self.jail.take() {
let _ = jail.kill();
}
}
}
}
Expand Down
38 changes: 38 additions & 0 deletions rust/src/tests/chflags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,5 +236,43 @@ enoent_comp_test_case!(chflags(~path, FileFlag::empty()));
// chflags/06.t
eloop_comp_test_case!(chflags(~path, FileFlag::empty()));

// chflags/09.t
#[cfg(target_os = "freebsd")]
crate::test_case! {
/// chflags returns EPERM when one of SF_IMMUTABLE, SF_APPEND, or SF_NOUNLINK is set and
/// securelevel is greater than 0
securelevel, root, FileSystemFeature::Chflags =>
[Regular, Dir, Fifo, Block, Char, Socket, Symlink(None)]
}
#[cfg(target_os = "freebsd")]
fn securelevel(ctx: &mut TestContext, ft: FileType) {
use jail::process::Jailed;
use std::ffi::OsStr;
use std::os::unix::ffi::OsStrExt;

let jail = jail::StoppedJail::new("/")
.name("pjdfstest_chflags_securelevel")
.param("allow.chflags", jail::param::Value::Int(1))
.param("securelevel", jail::param::Value::Int(1));
let jail = jail.start().unwrap();
ctx.set_jail(jail);

for flag in [FileFlags::SF_IMMUTABLE, FileFlags::SF_APPEND, FileFlags::SF_NOUNLINK] {
let file = ctx.create(ft.clone()).unwrap();
lchflags(&file, flag.into()).unwrap();

// Since this is a multithreaded application, we can't simply fork and chflags(). Instead,
// execute a child process to test the operation.
let r = std::process::Command::new("/bin/chflags")
.args(["-h", "0"])
.arg(ctx.base_path().join(&file))
.jail(&jail)
.output()
.unwrap();
assert!(!r.status.success());
assert!(OsStr::from_bytes(&r.stderr).to_string_lossy().contains("Operation not permitted"));
}
}

// chflags/13.t
efault_path_test_case!(chflags, |ptr| nix::libc::chflags(ptr, 0));

0 comments on commit fb297b9

Please sign in to comment.