Skip to content

Commit

Permalink
Initial ruleset duplication
Browse files Browse the repository at this point in the history
  • Loading branch information
int5-grey committed Mar 21, 2024
1 parent 89797a0 commit 768bf95
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/compat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ fn compat_state_update_2() {
}

#[cfg_attr(test, derive(Debug, PartialEq))]
#[derive(Clone)]
#[derive(Copy, Clone)]
pub(crate) struct Compatibility {
abi: ABI,
pub(crate) level: Option<CompatLevel>,
Expand Down
49 changes: 49 additions & 0 deletions src/ruleset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,32 @@ impl RulesetCreated {
};
Ok(body()?)
}

/// Creates a copy of this object and duplicates the file descriptor with
/// CLOEXEC set. The `RulesetCreated` object that is produced is intended
/// to be a readonly copy of the original object, however this
/// is not currently supported by the landlock kernel module. The intention
/// behind this method is to provide a way to keep a parent ruleset intact so
/// it can be applied to any number of new processes or threads without
/// creating the object over and over.
///
/// Any modification of the underlying ruleset changes will alter both
/// the new RulesetCreated and the original.
///
/// On error, returns a wrapped [`RulesetError::NewRef`].
pub fn new_ref(&self) -> Result<RulesetCreated, std::io::Error> {
let dup_fd = unsafe { libc::fcntl(self.fd, libc::F_DUPFD_CLOEXEC, 0) };
if dup_fd == -1 {
return Err(Error::last_os_error());
}

Ok(RulesetCreated {
fd: dup_fd,
no_new_privs: self.no_new_privs,
requested_handled_fs: self.requested_handled_fs,
compat: self.compat,
})
}
}

impl Drop for RulesetCreated {
Expand Down Expand Up @@ -719,6 +745,29 @@ fn ruleset_created_attr() {
);
}

#[test]
fn ruleset_created_new_ref() {
Ruleset::from(ABI::V1)
.handle_access(AccessFs::Execute)
.unwrap()
.create()
.unwrap()
.add_rule(PathBeneath::new(
PathFd::new("/usr").unwrap(),
AccessFs::Execute,
))
.unwrap()
.add_rule(PathBeneath::new(
PathFd::new("/etc").unwrap(),
AccessFs::Execute,
))
.unwrap()
.new_ref()
.unwrap()
.restrict_self()
.unwrap();
}

#[test]
fn ruleset_unsupported() {
assert_eq!(
Expand Down

0 comments on commit 768bf95

Please sign in to comment.