fix(sandbox): probe Landlock before build, skip on unsupported kernels#1585
Merged
Merged
Conversation
On kernels without Landlock (e.g. gVisor's sentry returns ENOSYS for syscall 444), the previous best_effort path still logged "Applying Landlock" + "Landlock ruleset built" events even though no enforcement was happening. Probe at the top of `landlock::prepare` and short-circuit with a single High-severity "Sandbox Unavailable" finding. Signed-off-by: Davanum Srinivas <dsrinivas@nvidia.com>
Contributor
Author
drew
approved these changes
May 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
On kernels without Landlock (e.g. gVisor's sentry returns
ENOSYSfor syscall 444), the previousbest_effortpath inlandlock::preparestill logged "Applying Landlock" + "Landlock ruleset built" OCSF events even though no enforcement was happening. This PR probes the kernel up-front and short-circuits with a single High-severity "Sandbox Unavailable" finding when Landlock isn't available, so the log stream no longer implies enforcement where there is none.Related Issue
No upstream-tracked issue. Surfaced while running OpenShell's supervisor under Agent Substrate's gVisor-backed actors — the sentry refuses Landlock syscalls and the existing best-effort path was producing self-contradictory log output (HIGH-severity "Sandbox Unavailable" finding alongside two INFO events implying the ruleset was applied).
Changes
crates/openshell-sandbox/src/sandbox/linux/landlock.rs: inprepare(), callprobe_availability()at the top of the path-validation block (after the no-paths early return, before the "Applying Landlock" event). If the probe returns anything other thanAvailable { .. }:BestEffort→ emit one High-severityDetectionFinding("Landlock Filesystem Sandbox Unavailable") and returnOk(None). No more "Applying" / "Built" events when there's nothing to apply.HardRequirement→ returnErr(...)so the supervisor aborts.try_open_path/enforcefailure paths are untouched — those continue to handle per-path failures andrestrict_self()failures respectively.Testing
Local Rust-side checks against the touched crate (
openshell-sandbox):cargo fmt --all -- --check— cleancargo check -p openshell-sandbox— cleancargo clippy -p openshell-sandbox --all-targets -- -D warnings— cleancargo test -p openshell-sandbox— 786 passed, 0 failed, 1 ignored (coverslandlock::testsincludingprobe_availability_returns_a_result,try_open_path_*,classify_*)mise run ciwas attempted but failed in my local environment on thepython:prototask withModuleNotFoundError: No module named 'grpc_tools'— Python dep not installed on my Mac, unrelated to this change. The Rust subtasks (rust:check,rust:lint,test:rust) were SIGTERM'd by mise when the parallelpython:prototask failed; I ran them directly instead with the results above.mise run pre-commitchecks I could run pass (Rust fmt/check/clippy/test, helm:lint, markdown:lint)probe_availability_returns_a_result(covers the probe call site) plus the existingBestEffort/HardRequirementmatchers; a deeper test would require refactoringprepare()to accept an injectable probe function, which felt out of scope for a 39-line log-shape fix.Checklist
fix(sandbox): probe Landlock before build, skip on unsupported kernels