fix(marmel): allow /nix/store in the Landlock sandbox
The upstream ruleset allow-lists FHS paths only (/usr, /bin, /lib, /opt, /etc, /var), and every executable here resolves below the store: /bin/sh is a symlink into /nix/store/<hash>-bash-5.3p9/bin/sh. Landlock matches the resolved target rather than the symlinked view, so the harness re-entry (`marmel --internal-sandbox-exec`) cannot exec the shell and every shell tool call comes back as "Failed to exec shell in sandbox: Permission denied (os error 13)" with exit 1. The sandbox is on by default, so the only workaround on a Nix host is MARMEL_DISABLE_SANDBOX=1, which drops the protection altogether. The patch adds "/nix/store" to the read-only+execute list, guarded by exists() like its neighbours. Store paths are world-readable by design, so the added reach is nothing a local user did not already have. Checked against the built binary: sandboxed exec works, git runs, workspace writes work, ~/.ssh and /root stay blocked. Tested: nix build .#marmel passes, lib suite 966 passed / 0 failed with one filter. test_internal_sandbox_cross_directory_rename no longer needs a skip and passes; test_internal_sandbox_exec_dev_null_and_dns stays skipped for its own reason, the no-network build sandbox has no /etc/resolv.conf. Temporary downstream fix, drop it once upstream takes the store path (nix-overlay-5ml).
This commit is contained in:
+14
-17
@@ -23,7 +23,14 @@ rustPlatform.buildRustPackage rec {
|
||||
|
||||
nativeCheckInputs = [ cacert ];
|
||||
|
||||
patches = [ ./session-boot-trust-store.patch ];
|
||||
patches = [
|
||||
./session-boot-trust-store.patch
|
||||
# Temporary downstream fix, upstream has no NixOS-aware allow-list yet.
|
||||
# Adds "/nix/store" to the read-only+execute list of the Landlock ruleset, so the
|
||||
# sandbox re-entry can exec `sh` on a Nix host at all. Drop when upstream lands it
|
||||
# (nix-overlay-5ml).
|
||||
./landlock-nix-store.patch
|
||||
];
|
||||
|
||||
# The test suite builds `reqwest::Client`s, and rustls rejects construction
|
||||
# outright when no system trust store is found ("No CA certificates were
|
||||
@@ -44,27 +51,17 @@ rustPlatform.buildRustPackage rec {
|
||||
# then 1 failure, then 0 with serial threads. Drop this flag once upstream
|
||||
# makes that state per-instance.
|
||||
#
|
||||
# The two sandbox-exec tests are skipped. They re-exec `sh` through
|
||||
# `marmel --internal-sandbox-exec`, and apply_landlock_linux() allow-lists
|
||||
# FHS paths only (/usr, /bin, /lib, /opt, /etc, /var) plus /tmp. Landlock
|
||||
# matches inodes rather than symlinked views, and every binary on NixOS
|
||||
# resolves into the store (`/bin/sh` is
|
||||
# /nix/store/<hash>-bash-interactive-5.3p9/bin/bash), so the exec is denied:
|
||||
# "Failed to exec shell in sandbox: Permission denied (os error 13)". Checked
|
||||
# against this build on a NixOS host, where the same command succeeds once
|
||||
# the workspace root is `/` and therefore covers /nix/store. Inside the build
|
||||
# sandbox the tests are doubly impossible: /usr, /lib, /run and /var do not
|
||||
# exist, so the `if let Ok(fd)` guards silently drop those rules, and
|
||||
# /etc/resolv.conf is absent because the sandbox has no network. 342 of 344
|
||||
# tests still run. Upstream main still carries the FHS-only list; drop these
|
||||
# skips if that ever gains /nix/store.
|
||||
# Only the DNS sandbox-exec test is skipped now. It re-execs `sh` through
|
||||
# `marmel --internal-sandbox-exec` and then reads /etc/resolv.conf, which the
|
||||
# no-network build sandbox does not provide. landlock-nix-store.patch fixed the
|
||||
# exec half for both sandbox-exec tests: with it, the cross-directory rename
|
||||
# test runs for real (no SKIP printed by `integration_host`) and the lib suite
|
||||
# passes at 966 tests with that single filter.
|
||||
cargoTestFlags = [
|
||||
"--"
|
||||
"--test-threads=1"
|
||||
"--skip"
|
||||
"harness::sandbox::tests::test_internal_sandbox_exec_dev_null_and_dns"
|
||||
"--skip"
|
||||
"harness::sandbox::tests::test_internal_sandbox_cross_directory_rename"
|
||||
];
|
||||
|
||||
# Role prompts are embedded with `include_str!`, so the binary needs no
|
||||
|
||||
Reference in New Issue
Block a user