Skip to content

Commit

Permalink
src: Execute each restrict_self() test in a dedicated thread
Browse files Browse the repository at this point in the history
Ensures restrict_self() is called on a dedicated thread to avoid
inconsistent tests.

The visible effect (with Rust 1.63) was for restrict_self() to sometime
return E2BIG because of too many stacked domains. This inconsistency was
related to the number of tests (i.e. the number of successful
restrict_self() calls), but not directly related to their content.

Signed-off-by: Mickaël Salaün <[email protected]>
  • Loading branch information
l0kod committed Aug 31, 2023
1 parent ce5727e commit dbd4105
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 25 deletions.
25 changes: 14 additions & 11 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,15 @@ mod tests {
check: F,
error_if_abi_lt_partial: bool,
) where
F: Fn(Ruleset) -> Result<RestrictionStatus, TestRulesetError>,
F: Fn(Ruleset) -> Result<RestrictionStatus, TestRulesetError> + Send + Copy + 'static,
{
// If there is no partial support, it means that `full == partial`.
assert!(partial <= full.unwrap_or(partial));
for abi in ABI::iter() {
let ret = check(Ruleset::from(abi));
// Ensures restrict_self() is called on a dedicated thread to avoid inconsistent tests.
let ret = std::thread::spawn(move || check(Ruleset::from(abi)))
.join()
.unwrap();

// Useful for failed tests and with cargo test -- --show-output
println!("Checking ABI {abi:?}: received {ret:#?}");
Expand Down Expand Up @@ -178,7 +181,7 @@ mod tests {
check_ruleset_support(
abi,
Some(abi),
|ruleset: Ruleset| -> _ {
move |ruleset: Ruleset| -> _ {
Ok(ruleset
.handle_access(AccessFs::from_all(abi))?
.create()?
Expand All @@ -196,7 +199,7 @@ mod tests {
check_ruleset_support(
abi,
Some(abi),
|ruleset: Ruleset| -> _ {
move |ruleset: Ruleset| -> _ {
Ok(ruleset
.handle_access(AccessFs::from_all(abi))?
.create()?
Expand All @@ -214,7 +217,7 @@ mod tests {
check_ruleset_support(
abi,
None,
|ruleset: Ruleset| -> _ {
move |ruleset: Ruleset| -> _ {
Ok(ruleset
.handle_access(AccessFs::from_all(abi))?
.create()?
Expand All @@ -237,7 +240,7 @@ mod tests {
check_ruleset_support(
abi,
Some(abi),
|ruleset: Ruleset| -> _ {
move |ruleset: Ruleset| -> _ {
Ok(ruleset
.handle_access(AccessFs::from_all(ABI::V1))?
.create()?
Expand All @@ -256,7 +259,7 @@ mod tests {
check_ruleset_support(
abi,
Some(abi),
|ruleset: Ruleset| -> _ {
move |ruleset: Ruleset| -> _ {
// Sets default support requirement: abort the whole sandboxing for any Landlock error.
Ok(ruleset
// Must have at least the execute check…
Expand All @@ -281,7 +284,7 @@ mod tests {
check_ruleset_support(
abi,
Some(abi),
|ruleset: Ruleset| -> _ {
move |ruleset: Ruleset| -> _ {
Ok(ruleset
// Restricting without rule exceptions is legitimate to forbid a set of actions.
.handle_access(AccessFs::Execute)?
Expand All @@ -297,7 +300,7 @@ mod tests {
check_ruleset_support(
ABI::V1,
Some(ABI::V2),
|ruleset: Ruleset| -> _ {
move |ruleset: Ruleset| -> _ {
Ok(ruleset
.handle_access(AccessFs::Execute)?
// AccessFs::Refer is not supported by ABI::V1 (best-effort).
Expand All @@ -315,7 +318,7 @@ mod tests {
check_ruleset_support(
ABI::V2,
Some(ABI::V2),
|ruleset: Ruleset| -> _ {
move |ruleset: Ruleset| -> _ {
Ok(ruleset
.handle_access(AccessFs::Refer)?
.create()?
Expand All @@ -330,7 +333,7 @@ mod tests {
check_ruleset_support(
ABI::V2,
Some(ABI::V3),
|ruleset: Ruleset| -> _ {
move |ruleset: Ruleset| -> _ {
Ok(ruleset
.handle_access(AccessFs::Refer)?
.handle_access(AccessFs::Truncate)?
Expand Down
34 changes: 20 additions & 14 deletions src/ruleset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -663,20 +663,26 @@ fn ruleset_created_attr() {
.unwrap();

// ...and finally restrict with the last rules (thanks to non-lexical lifetimes).
ruleset_created
.set_compatibility(CompatLevel::BestEffort)
.add_rule(PathBeneath::new(
PathFd::new("/tmp").unwrap(),
AccessFs::Execute,
))
.unwrap()
.add_rule(PathBeneath::new(
PathFd::new("/var").unwrap(),
AccessFs::Execute,
))
.unwrap()
.restrict_self()
.unwrap();
assert_eq!(
ruleset_created
.set_compatibility(CompatLevel::BestEffort)
.add_rule(PathBeneath::new(
PathFd::new("/tmp").unwrap(),
AccessFs::Execute,
))
.unwrap()
.add_rule(PathBeneath::new(
PathFd::new("/var").unwrap(),
AccessFs::Execute,
))
.unwrap()
.restrict_self()
.unwrap(),
RestrictionStatus {
ruleset: RulesetStatus::NotEnforced,
no_new_privs: true,
}
);
}

#[test]
Expand Down

0 comments on commit dbd4105

Please sign in to comment.