fix(task): preserve essential env vars under deny_env on Linux#9467
Conversation
env_clear() in apply_sandbox() ran after the task executor had already populated Command with the filtered env (PATH, HOME, USER, SHELL, TERM, LANG plus any allow_env entries), wiping them all. Save the explicit envs, clear, then restore — matching the existing macOS path. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Greptile SummaryThis PR fixes a Linux-specific regression where Confidence Score: 5/5Safe to merge — the fix is minimal, targeted, and matches the established macOS pattern. No P0/P1 issues found. The save-then-restore pattern correctly mirrors how the macOS branch already handled this. get_envs() returning None for explicitly-removed vars is correctly handled by the filter_map. A regression test exercises the new code path in CI on Linux. No files require special attention. Important Files Changed
Sequence DiagramsequenceDiagram
participant TE as task_executor
participant CMD as Command
participant AS as apply_sandbox()
participant PROC as Child Process
TE->>CMD: .envs(filter_env(env))
TE->>AS: apply_sandbox()
note over AS: effective_deny_env() == true
AS->>CMD: get_envs() → save explicitly-set vars
AS->>CMD: env_clear() (wipes inherited + explicit)
AS->>CMD: re-apply saved vars (PATH, HOME, ...)
AS->>CMD: pre_exec(landlock/seccomp)
CMD->>PROC: spawn() — child sees only filtered vars
Reviews (1): Last reviewed commit: "fix(task): preserve essential env vars u..." | Re-trigger Greptile |
There was a problem hiding this comment.
Code Review
This pull request updates the Linux command runner to ensure that environment variables explicitly set via .envs() are preserved when deny_env is enabled, as env_clear() previously wiped them. It also adds an end-to-end test to verify that essential environment variables like PATH and HOME remain accessible under these conditions. I have no feedback to provide.
Hyperfine Performance
|
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.4.25 x -- echo |
23.4 ± 0.7 | 22.0 | 34.0 | 1.00 |
mise x -- echo |
24.6 ± 0.9 | 22.6 | 30.0 | 1.05 ± 0.05 |
mise env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.4.25 env |
22.9 ± 0.8 | 21.3 | 29.7 | 1.00 |
mise env |
23.7 ± 0.6 | 22.3 | 25.8 | 1.04 ± 0.04 |
mise hook-env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.4.25 hook-env |
23.2 ± 0.7 | 22.1 | 28.5 | 1.00 |
mise hook-env |
24.4 ± 0.6 | 23.0 | 27.2 | 1.05 ± 0.04 |
mise ls
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.4.25 ls |
24.1 ± 0.5 | 23.0 | 26.5 | 1.00 |
mise ls |
24.9 ± 0.5 | 23.6 | 27.5 | 1.03 ± 0.03 |
xtasks/test/perf
| Command | mise-2026.4.25 | mise | Variance |
|---|---|---|---|
| install (cached) | 158ms | 164ms | -3% |
| ls (cached) | 81ms | 84ms | -3% |
| bin-paths (cached) | 82ms | 85ms | -3% |
| task-ls (cached) | 861ms | 818ms | +5% |
Summary
deny_env = trueon Linux, every env var was stripped from the child process — including thePATH/HOME/USER/SHELL/TERM/LANGthat the docs andfilter_envsay should pass through.apply_sandbox()calledCommand::env_clear()aftertask_executorhad already populated the command via.envs(filtered_env).env_clear()wipes both inherited and explicitly-set envs, leaving an empty environment. The macOS branch already handled this (it builds a new command and copies the envs over); the Linux branch did not.env_clear()(still needed to prevent parent inheritance), then re-apply the saved envs.e2e/sandbox/test_sandbox_taskwith apath_testtask that assertsPATHandHOMEare non-empty underdeny_env, so this regression gets caught next time.Test plan
cargo buildcargo test --bin mise sandbox::testsmise run test:e2e sandbox/test_sandbox_task(passes on macOS; new assertions exercise the Linux-only code path in CI)mise run lint-fix🤖 Generated with Claude Code
Note
Medium Risk
Touches process execution/sandbox setup on Linux; mistakes could leak env vars or break task execution, but the change is small and covered by a new regression test.
Overview
Fixes Linux
deny_envsandbox behavior so clearing inherited environment variables no longer removes env vars explicitly set on theCommand(e.g., filtered essentials likePATH/HOME). It snapshotsCommand::get_envs(), callsenv_clear(), then restores the saved key/values before applying Landlock/seccomp.Adds an e2e regression check (
sandbox/test_sandbox_task) that verifiesdeny_envstill preservesPATHandHOMEwhile continuing to hide a secret env var.Reviewed by Cursor Bugbot for commit 9b6eca7. Bugbot is set up for automated code reviews on this repo. Configure here.