Skip to content

core: use landlock crate - #305

Merged
congwang-mk merged 1 commit into
multikernel:mainfrom
aeryz:286-use-landlock-crate
Oct 25, 2026
Merged

congwang-mk merged 1 commit into
multikernel:mainfrom
aeryz:286-use-landlock-crate

Conversation

@aeryz

@aeryz aeryz commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

Instead of writing our own landlock wrapper, we now use the landlock crate. This will ease up handling of the landlock ops on multiple kernel versions.

Fixes #286

))
})?;
let status = ruleset.restrict_self()?;
if status.ruleset != RulesetStatus::FullyEnforced {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check is load-bearing, not a sanity check: any try_compat failure under HardRequirement makes the crate state Dummy permanently, after which add_rule and restrict_self return Ok without syscalls (NotEnforced). The ignored let _ = add_rule(...) calls rely on this guard to fail closed. Please add a comment saying so, ideally a test too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! But tbf, API-wise, it's a bit nasty to first return an error, then return Ok for the consequent calls. Let's still have this as a sanity-check but I'd say let's not ignore the errors on add_rule. Right now, we already check whether the path exists - and successfully opened - by checking the result of path_beneath_rule. After that, we should not ignore the result of add_rule since it'd be catched in the FullyEnforced check anyways.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left this as is impl-wise. Added a comment on the behaviour and a test that covers it.

} else {
LANDLOCK_ACCESS_NET_BIND_TCP | LANDLOCK_ACCESS_NET_CONNECT_TCP
};
let mut mask = AccessNet::from_all(abi);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from_all(abi) silently widens with crate bumps. If a future AccessNet gains e.g. UDP, it becomes handled with no rules, denying all UDP. Prefer explicit BindTcp | ConnectTcp, or add exact-mask tests at ABI::V9 (same for AccessFs::from_all in compute_fs_mask).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Both places are now explicit.

Comment thread crates/sandlock-core/src/protection.rs Outdated
/// Minimum Landlock ABI version the host kernel must support for
/// this protection to be available.
pub const fn min_abi(self) -> u32 {
pub const fn min_abi(self) -> landlock::ABI {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exposing landlock::ABI (here, ProtectionStatus::resolve, ProtectionUnavailable fields, compute_*_mask return types) makes every landlock crate bump a sandlock-core breaking change, and the CLI/FFI/tests now cast back to u32. Suggest keeping u32 publicly and converting inside confine_inner/active_protections.

@aeryz aeryz Oct 25, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, now only converting to ABI when we have to to use the landlock crate.

SandlockError::Runtime(crate::error::SandboxRuntimeError::Confinement(e))
})?;

ruleset = ruleset.add_rule(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kernel-side add_rule failures used to report add path rule for {path} / add net rule for port {port}; now the bare RulesetError loses the path/port. Please re-wrap with that context (also the net rules below).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done by adding the add_net_rule and add_path_beneath_rule helpers.

ConfinementError::Landlock(format!("restrict_self: {}", e)),
))
})?;
let status = ruleset.restrict_self()?;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: the crate sets PR_SET_NO_NEW_PRIVS by default here, but every caller already does. .no_new_privs(false) would keep that responsibility in one place.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, now using no_new_privs(false) and explicitly mentioning it in the public function warning the callers.

if supervised && shadowed_files().any(|f| f.starts_with(path)) {
add_read_rules_around_shadowed(&ruleset_fd, path).map_err(|e| {
ruleset = add_read_rules_around_shadowed(ruleset, path).map_err(|e| {
SandlockError::Runtime(crate::error::SandboxRuntimeError::Confinement(e))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Three error-conversion paths now: From<RulesetError> for SandlockError, cast_confinement, and this inline closure. Pick one.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed by only using From<ConfinementError> for SandlockError. It helps with not manually wrapping SandlockError::Runtime all the time.

@aeryz
aeryz force-pushed the 286-use-landlock-crate branch 2 times, most recently from 7fb1aad to 7194982 Compare October 25, 2026 11:11
Instead of writing our own landlock wrapper, we
now use `landlock` crate. This will ease up handling
of the landlock ops on multiple kernel versions.

Signed-off-by: kernelnomad <kernelnomad@proton.me>
@aeryz
aeryz force-pushed the 286-use-landlock-crate branch from 7194982 to 643cb09 Compare October 25, 2026 11:18
@congwang-mk
congwang-mk merged commit fc92a56 into multikernel:main Oct 25, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Switch to landlock crate

2 participants