microsoft / microsoft/mxc

Default PATH behavior is inconsistent across Linux and macOS backends

Open
#1,153 0 comments 0 reactions 1 assignee Claimed by @theelliotm View on GitHub
Issue-Bug OS-Linux OS-MacOS Priority1
Dominant language
Rust
Stars
1.3k
Forks
79
Avg merge
2d 7h
Merged PRs (30d)
117

Description

### Relevant area(s)

Linux, macOS

### Brief description of your issue

The non-Windows containment backends do not share a documented contract for the default `PATH` supplied to sandboxed workloads. This issue is split from #1102 after PR #1120 aligned the Windows ProcessContainer environment behavior.

Current behavior still differs by backend:

| Backend | `process.env` omitted | `process.env` set, no `PATH=` |
|---|---|---|
| Seatbelt (macOS) | `/usr/bin:/bin:/usr/sbin:/sbin` | same default |
| LXC (Linux) | inherits host `PATH` | liblxc default `/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin` |
| Bubblewrap (Linux) | no `PATH` supplied by MXC | no `PATH` supplied by MXC |

Bubblewrap clears the environment without restoring `PATH`, so command resolution falls back to the shell's distro-specific compiled default. This has produced different results between Debian/Ubuntu and RHEL. LXC also changes its `PATH` behavior when an unrelated environment variable is added because a non-empty `process.env` switches it from inherited environment behavior to liblxc's cleared-environment default. Seatbelt supplies a stable default, but that contract is not shared or documented across the non-Windows backends.

### Steps to reproduce

1. Build MXC on Linux or macOS.
2. Run a config that prints `PATH` and resolves a command normally found under `sbin`, with `process.env` omitted.
3. Add an unrelated variable such as `"env": ["FOO=bar"]` and run the same config again.
4. Compare Bubblewrap and LXC on Debian/Ubuntu and RHEL, and compare Seatbelt on macOS.

Example process configuration:

```json
"process": {
"commandLine": "bash -c 'echo \"PATH=[${PATH-}]\"; command -v iptables || echo NO_IPTABLES'"
}
```

### Expected behavior

Linux and macOS backends follow a single documented default-environment contract. Adding an unrelated environment variable does not unexpectedly change command resolution.

### Actual behavior

Bubblewrap can leave `PATH` unset, LXC switches between the host path and liblxc's default based on whether `process.env` is non-empty, and Seatbelt applies a separate fixed default. Command resolution therefore varies by backend and host distribution.

Additional context: nightly run [33731889129](https://github.com/microsoft/mxc/actions/runs/33731889129) failed on RHEL 10 while the Debian/Ubuntu Bubblewrap jobs passed because their shell fallback paths included `sbin`.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.