Skip to content

fix(mcl.utils.deploy-state): stop the ancestor guard rejecting what the walk accepted - #598

Merged
zah merged 1 commit into
devfrom
fix/mcl-deploy-state-sandbox-and-sticky-parent
Aug 24, 2026
Merged

zah merged 1 commit into
devfrom
fix/mcl-deploy-state-sandbox-and-sticky-parent

Conversation

@zah

@zah zah commented Aug 23, 2026

Copy link
Copy Markdown
Member

Four CI checks have been red on dev since c85f2a00 (2026-08-11). They are one bug with two faces.

Face 1 — the parent is validated twice, under two different policies

openOrCreateStateDirectory re-validates the parent descriptor that openOrCreateTrustedParentDirectory has just validated, but under a stricter policy with no sticky-bit exemption. So the ancestor walk accepts /tmp and the very next statement rejects it:

deploy_state.d(314): Deployment state directory parent /tmp is writable by its group or other users

Fails: deployment-direct-ssh-success-vm, deployment-reconciler-supersession-vm, deployment-production-cutover-simulation-vm.

Face 2 — the walk anchor is unreachable in the Nix Linux sandbox

The walk required its anchor to be owned by root or the deploy user. Inside the sandbox / is uid 65534, mode 0750 (probed directly), so every absolute state directory is unreachable:

deploy_state.d(376): walk anchor is not owned by root or the effective deployment user

This is why deployment-darwin-activation-integration passes on aarch64-darwin and fails on x86_64-linux — same code, different sandbox.

Verification

All 134 mcl unit tests pass, including a new regression test for a state directory sitting directly inside a sticky parent. All four checks build and pass locally.

Classification was proved rather than assumed: each check's drvPath is byte-identical on dev and on the GARM PR that surfaced them (e.g. deployment-direct-ssh-success-vm = hhbckrxnbc90h20ma8b7xvid3c7749ka on both), and that hash matches the one in the CI failure log. PRs #593, #595 and #577 — none related — fail the identical set.

…n walk

c85f2a0 hardened the deployment state directory against symlink and
ownership attacks. Two of its rules cannot be satisfied by the places
deployments actually keep state, and every deploy_state-using check has
been red since.

1. openOrCreateStateDirectory() re-validated the parent descriptor that
   openOrCreateTrustedParentDirectory() had *just* validated, but under a
   different policy: validateDirectoryDescriptor() has no sticky-directory
   exemption. So the walk accepted /tmp (root-owned, 01777) as an ancestor
   and the very next statement rejected it as a parent. Any
   `--state-dir /tmp/<name>` — which is what deployment-direct-ssh-success-vm,
   deployment-reconciler-supersession-vm and
   deployment-production-cutover-simulation-vm all pass — died with
   "Deployment state directory parent /tmp is writable by its group or
   other users." The parent is an ancestor; validate it once, by the
   ancestor rule.

2. The walk anchor was required to be owned by root or by the effective
   deployment user. The anchor is "/" (or the process working directory),
   never a component the caller picked, and inside a chroot or user
   namespace it is legitimately owned by neither: in the Nix Linux build
   sandbox "/" is uid 65534, mode 0750. That made *every* absolute state
   directory unreachable from a Linux sandbox and broke
   deployment-darwin-activation-integration on x86_64-linux, while the
   same check stayed green on aarch64-darwin where the sandbox has a real
   root. Validate the anchor for what it can actually promise — that no
   other user may plant entries in it — and keep the full ownership check
   on every named component below it.

Add a regression test placing the state directory directly inside a
world-writable sticky parent, which is the shape all of the above use and
which no existing test covered.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 23, 2026 •

Copy link
Copy Markdown
Contributor

Thanks for your Pull Request!

Below you will find a summary of the cachix status of each package, for each supported platform.

package x86_64-linux x86_64-darwin aarch64-darwin
attic-migrate-flake ❌ build failed 🚫 not supported ❌ build failed
attic-migrate-flake-idempotent ❌ build failed 🚫 not supported ❌ build failed
attic-push-flake-outputs-action ❌ build failed 🚫 not supported ❌ build failed
aztec ❌ build failed 🚫 not supported ❌ build failed
cachix ❌ build failed 🚫 not supported ❌ build failed
cachix-deploy-metrics ❌ build failed 🚫 not supported ❌ build failed
ci-image ❌ build failed 🚫 not supported 🚫 not supported
consumer-flake-cachix-inventory ❌ build failed 🚫 not supported ❌ build failed
consumer-flake-cachix-inventory-tool ❌ build failed 🚫 not supported ❌ build failed
consumer-flake-no-cachix-residual ❌ build failed 🚫 not supported ❌ build failed
consumer-flake-no-cachix-residual-tool ❌ build failed 🚫 not supported ❌ build failed
dcd ❌ build failed 🚫 not supported 🚫 not supported
deployment-attic-nginx-logs-vm ❌ build failed 🚫 not supported 🚫 not supported
deployment-attic-push-substitute-vm ❌ build failed 🚫 not supported 🚫 not supported
deployment-break-glass-runbook-sections ❌ build failed 🚫 not supported ❌ build failed
deployment-cache-backend-policy ❌ build failed 🚫 not supported ❌ build failed
deployment-cache-corruption-vm ❌ build failed 🚫 not supported 🚫 not supported
deployment-cachix-fallback-simulation ❌ build failed 🚫 not supported 🚫 not supported
deployment-current-flow-inventory ❌ build failed 🚫 not supported ❌ build failed
deployment-darwin-activation-integration ❌ build failed 🚫 not supported ❌ build failed
deployment-dashboard-query-fixtures ❌ build failed 🚫 not supported 🚫 not supported
deployment-direct-ssh-attic-restore-vm ❌ build failed 🚫 not supported 🚫 not supported
deployment-direct-ssh-rollback-vm ❌ build failed 🚫 not supported 🚫 not supported
deployment-direct-ssh-success-vm ❌ build failed 🚫 not supported 🚫 not supported
deployment-e2e-rehearsal-skill-doc ❌ build failed 🚫 not supported ❌ build failed
deployment-event-metrics ❌ build failed 🚫 not supported 🚫 not supported
deployment-event-schema-examples ❌ build failed 🚫 not supported ❌ build failed
deployment-incus-rehearsal-image ❌ build failed 🚫 not supported 🚫 not supported
deployment-incus-rehearsal-script-static ❌ build failed 🚫 not supported 🚫 not supported
deployment-metrics-vm ❌ build failed 🚫 not supported 🚫 not supported
deployment-no-default-cachix-deploy-call ❌ build failed 🚫 not supported 🚫 not supported
deployment-parallel-cache-push-local ❌ build failed 🚫 not supported 🚫 not supported
deployment-production-cutover-simulation-vm ❌ build failed 🚫 not supported 🚫 not supported
deployment-pull-agent-darwin-integration 🚫 not supported 🚫 not supported ❌ build failed
deployment-pull-agent-latest-vm ❌ build failed 🚫 not supported 🚫 not supported
deployment-pull-agent-lock-contention-vm ❌ build failed 🚫 not supported 🚫 not supported
deployment-pull-agent-locks-migration-vm ❌ build failed 🚫 not supported 🚫 not supported
deployment-pull-agent-rejects-invalid-vm ❌ build failed 🚫 not supported 🚫 not supported
deployment-pull-agent-selfheal-vm ❌ build failed 🚫 not supported 🚫 not supported
deployment-pull-agent-static ❌ build failed 🚫 not supported 🚫 not supported
deployment-reconciler-lock-contention-vm ❌ build failed 🚫 not supported 🚫 not supported
deployment-reconciler-skill-doc ❌ build failed 🚫 not supported ❌ build failed
deployment-reconciler-supersession-vm ❌ build failed 🚫 not supported 🚫 not supported
deployment-reconciler-timer-retry-vm ❌ build failed 🚫 not supported 🚫 not supported
deployment-reconciler-timer-static ❌ build failed 🚫 not supported 🚫 not supported
deployment-scheduled-canary-local-vm ❌ build failed 🚫 not supported 🚫 not supported
deployment-skill-doc-command-references ❌ build failed 🚫 not supported ❌ build failed
deployment-summary-artifact ❌ build failed 🚫 not supported ❌ build failed
desktop-vms-golden ❌ build failed 🚫 not supported 🚫 not supported
disko ❌ build failed 🚫 not supported 🚫 not supported
dmd ❌ build failed 🚫 not supported 🚫 not supported
dscanner ❌ build failed 🚫 not supported 🚫 not supported
dub ❌ build failed 🚫 not supported ❌ build failed
encrypted-s3-artifact ❌ build failed 🚫 not supported ❌ build failed
erigon ❌ build failed 🚫 not supported 🚫 not supported
folder-size-metrics ❌ build failed 🚫 not supported 🚫 not supported
foundry ❌ build failed 🚫 not supported ❌ build failed
garm ❌ build failed 🚫 not supported ❌ build failed
garm-provider-vmharness ❌ build failed 🚫 not supported ❌ build failed
geth ❌ build failed 🚫 not supported ❌ build failed
ldc ❌ build failed 🚫 not supported 🚫 not supported
lido-withdrawals-automation ❌ build failed 🚫 not supported ❌ build failed
linux-vm-cloud-init-image ❌ build failed 🚫 not supported 🚫 not supported
mcl ❌ build failed 🚫 not supported ❌ build failed
mev-boost ❌ build failed 🚫 not supported 🚫 not supported
netbird-with-agenix-login-script ❌ build failed 🚫 not supported 🚫 not supported
nethermind ❌ build failed 🚫 not supported 🚫 not supported
nimbus ❌ build failed 🚫 not supported 🚫 not supported
nix ✅ Cached at <0> 🚫 not supported ✅ Cached at <0>
nix-eval-jobs ✅ Cached at <0> 🚫 not supported ✅ Cached at <0>
nix-fast-build ✅ Cached at <0> 🚫 not supported ✅ Cached at <0>
nixos-anywhere ❌ build failed 🚫 not supported 🚫 not supported
nixos-rebuild-ng ❌ build failed 🚫 not supported ❌ build failed
pyroscope ❌ build failed 🚫 not supported ❌ build failed
random-alerts ❌ build failed 🚫 not supported ❌ build failed
reusable-flake-checks-artifact-fallback ❌ build failed 🚫 not supported ❌ build failed
reusable-flake-checks-attic-credentials ❌ build failed 🚫 not supported ❌ build failed
reusable-flake-checks-mcl-ref ❌ build failed 🚫 not supported ❌ build failed
reusable-terraform-drift-workflow ❌ build failed 🚫 not supported ❌ build failed
reusable-terraform-policy-advisories ❌ build failed 🚫 not supported ❌ build failed
rustToolchain ❌ build failed 🚫 not supported ❌ build failed
secret-integration ❌ build failed 🚫 not supported 🚫 not supported
serve-d ❌ build failed 🚫 not supported 🚫 not supported
setup-nix-transfer-resilience ❌ build failed 🚫 not supported ❌ build failed
t_cross_host_publish_substitute ❌ build failed 🚫 not supported 🚫 not supported
t_garm_api_watchdog ❌ build failed 🚫 not supported 🚫 not supported
t_garm_incus_runner_host ❌ build failed 🚫 not supported 🚫 not supported
t_garm_macos_runner_install_wrapper ❌ build failed 🚫 not supported ❌ build failed
t_garm_multi_provider ❌ build failed 🚫 not supported 🚫 not supported
t_garm_nixos_service_boots ❌ build failed 🚫 not supported 🚫 not supported
t_garm_provider_vmharness_protocol ❌ build failed 🚫 not supported 🚫 not supported
t_garm_provider_vmharness_windows_toolchain ❌ build failed 🚫 not supported ❌ build failed
t_garm_reconcile ❌ build failed 🚫 not supported 🚫 not supported
t_repro_binary_cache_systemd_healthz ❌ build failed 🚫 not supported 🚫 not supported
t_repro_cache_client_render ❌ build failed 🚫 not supported 🚫 not supported
t_repro_deploy_agent_https_converges ❌ build failed 🚫 not supported 🚫 not supported
t_repro_lease_reaper_eval ❌ build failed 🚫 not supported 🚫 not supported
t_s3_artifact_store_acl_and_creds ❌ build failed 🚫 not supported 🚫 not supported
terraform ❌ build failed 🚫 not supported 🚫 not supported
terraform-ci-matrix ❌ build failed 🚫 not supported ❌ build failed
terranix ❌ build failed 🚫 not supported 🚫 not supported
test-linux-vm-cloud-init ❌ build failed 🚫 not supported 🚫 not supported
test_darwin_pull_agent_assertion_gate 🚫 not supported 🚫 not supported ❌ build failed
test_darwin_pull_agent_entrypoint_survives_generation_change 🚫 not supported 🚫 not supported ❌ build failed
test_darwin_pull_agent_launchd_contract 🚫 not supported 🚫 not supported ❌ build failed
test_darwin_pull_agent_lock_contention_is_non_destructive 🚫 not supported 🚫 not supported ❌ build failed
test_darwin_pull_agent_rejects_invalid_durable_state 🚫 not supported 🚫 not supported ❌ build failed
test_darwin_pull_agent_rejects_untrusted_and_wrong_target_manifests 🚫 not supported 🚫 not supported ❌ build failed
test_darwin_pull_agent_same_id_sequence_high_water 🚫 not supported 🚫 not supported ❌ build failed
web3signer ❌ build failed 🚫 not supported 🚫 not supported
yaml-automation-runner ❌ build failed 🚫 not supported 🚫 not supported

@zah
zah merged commit 55bfe75 into dev Aug 24, 2026
159 of 163 checks passed
@zah
zah deleted the fix/mcl-deploy-state-sandbox-and-sticky-parent branch August 24, 2026 11:42
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.

1 participant