Proof Portal
Omarchy
ProbeLabs65 findings · 95 requirementsA proof layer — requirements, tests and verified fixes — for two of Omarchy's subsystems: the application menu (launcher scripts, QML model, JSONC config, search and selection) and the lock screen (lock scripts, QML, PAM authentication). Scope is deliberately limited to those components of omacom/omarchy; the rest of the distribution is not covered.
omarchy-windows-vm: launch permanently fails when a mount source has the setgid bit, because chmod 0700 cannot clear it
Reported by idrlmartian · filed Sep 6, 2026Closed upstream on 2026-09-20 by bjarneo via an automated message, as a duplicate of #9334 (R-1173). GitHub close reason: completed.
At a glance
- 1 · What is claimed?
- Only the report text below — no validator has restated it as checkable claims yet.
- 2 · What does it affect?
- Not yet mapped to any requirement or component.
- 3 · Is it reproducible?
- No validation has been run yet.
- 4 · What remains unclear?
- Not validated yet: no claims, no reproducer.
- 5 · What happens next?
- Our staff decide whether the report is valid. Where this project allows it, agents decide whether it duplicates another report or a known issue. No decision has been recorded yet.
Original report
Summary
If either VM mount source (~/Windows or ~/.windows) has the setgid bit set, omarchy-windows-vm launch fails permanently and unrecoverably with a generic error. The code contains a self-healing step intended to normalise these directories to 0700, but that step is a silent no-op against setgid, so the assertion immediately after it can never pass.
The user-visible symptom gives no hint of the cause:
Starting Windows VM (this may prompt for authorization)...
❌ Failed to start Windows VM!
Try checking: omarchy-windows-vm status...while omarchy-windows-vm status cheerfully reports RUNNING, because the container and guest are completely healthy. Only the launcher aborts — it exits before ever reaching xfreerdp3, so the VM is running and reachable but the user can never connect to it.
Root cause
prepare_caller_mounts normalises both mount sources, then verifies the result:
https://github.com/basecamp/omarchy/blob/main/bin/omarchy-windows-vm#L583
chmod 0700 -- "/proc/$BASHPID/fd/$storage_fd" "/proc/$BASHPID/fd/$shared_fd" || {
...
return 1
}
storage_mode=$(stat -Lc '%a' "/proc/$BASHPID/fd/$storage_fd" 2>/dev/null) || storage_mode=""
shared_mode=$(stat -Lc '%a' "/proc/$BASHPID/fd/$shared_fd" 2>/dev/null) || shared_mode=""
if [[ $storage_mode != 700 || $shared_mode != 700 ]]; then
...
return 1
fiGNU `chmod` deliberately preserves setuid/setgid bits on directories when given a numeric mode. This is documented behaviour, not a bug in coreutils — it exists so that chmod -R 755 over a tree does not strip setgid from shared group directories. From the coreutils manual:
the chmod command preserves a directory's set-user-ID and set-group-ID bits unless you explicitly specify otherwiseThe consequence here is that chmod 0700 on a 2700 directory returns exit status 0 and changes nothing. The || return 1 guard therefore never trips, and control falls through to the != 700 assertion, which compares 2700 against 700 and fails.
Measured on an affected directory (coreutils 9.11):
| command | resulting mode | exit |
|---|---|---|
chmod 0700 dir | 2700 — unchanged | 0 |
chmod 00700 dir | 700 | 0 |
chmod g-s dir | 700 | 0 |
os.chmod(dir, 0o700) (raw syscall) | 700 | — |
The raw chmod(2) syscall has no such special case, which is why the behaviour is surprising: it is purely a coreutils front-end rule.
Failure chain
~/Windowsis mode2700prepare_caller_mounts→chmod 0700is a no-op, returns 0[[ $shared_mode != 700 ]]→2700 != 700→return 1assert_mounts_safe→return 1__priv_up_wait→assert_mounts_safe || return 1priv up_waitfails →launch_windowsprints❌ Failed to start Windows VM!andexit 1
Because step 2 is the very mechanism meant to repair step 1, retrying can never succeed. The failure also surfaces four call frames away from its cause, with no diagnostic naming the offending path or mode.
Note that mounts_ready failing on the unprivileged fast path also silently pushes every launch onto the pkexec path, so affected users get an authorization prompt on every attempt before it fails anyway.
Reproduction
chmod g+s ~/Windows # or ~/.windows
omarchy-windows-vm launch # ❌ Failed to start Windows VM!
omarchy-windows-vm launch # fails identically, foreverRecovery (this is also the user-side workaround):
chmod g-s ~/Windows
omarchy-windows-vm launch # worksI hit this on a real install rather than synthetically — ~/Windows had somehow acquired the setgid bit. I was not able to determine what set it; omarchy-windows-vm itself never sets setgid anywhere, so the bit most likely arrived from outside the VM tooling (an inherited mode, an archive extraction, or a file manager). That makes it worth handling defensively regardless of origin, since the tool cannot currently recover from a state it can plausibly encounter.
Suggested fix
Use a mode form that actually clears the bits. Either the 5-digit numeric form or the symbolic form works:
- chmod 0700 -- "/proc/$BASHPID/fd/$storage_fd" "/proc/$BASHPID/fd/$shared_fd" || {
+ chmod 00700 -- "/proc/$BASHPID/fd/$storage_fd" "/proc/$BASHPID/fd/$shared_fd" || {The same applies at line 1018 (chmod 0700 -- "$storage" "$shared"), which normalises the same two directories during install and would leave a freshly-created VM in the identical broken state. Line 1061 (chmod 0700 "$dir" for the credentials directory) is not currently mode-asserted, but is the same latent hazard and is worth changing for consistency.
Given the security intent of this code path, 00700 seems preferable to g-s: it states the complete target mode explicitly rather than subtracting one bit from whatever was there.
Separately, it would help a great deal if the assertion reported what it rejected, e.g.:
if [[ $storage_mode != 700 || $shared_mode != 700 ]]; then
echo "omarchy-windows-vm: refusing mount source with unexpected mode" \
"(storage=$storage_mode shared=$shared_mode, expected 700)" >&2As it stands, every distinct failure in assert_mounts_safe collapses into the same ❌ Failed to start Windows VM! string, which is what made this take a while to track down — particularly since status simultaneously reports RUNNING.
Environment
- omarchy 4.0.2-1 (reported version string
4.0.0.alpha), Arch Linux - Bug confirmed present on
mainas of58c399de, same line numbers - GNU coreutils 9.11
- Kernel 7.1.9-arch1
- Docker 29.7.2,
dockurr/windowsv6.05 - Reproduced on btrfs; the behaviour is a coreutils front-end rule, so it is filesystem-independent (I verified identical results on btrfs, tmpfs and
/var/tmp)
View raw text
## Summary
If either VM mount source (`~/Windows` or `~/.windows`) has the setgid bit set, `omarchy-windows-vm launch` fails **permanently and unrecoverably** with a generic error. The code contains a self-healing step intended to normalise these directories to `0700`, but that step is a silent no-op against setgid, so the assertion immediately after it can never pass.
The user-visible symptom gives no hint of the cause:
```
Starting Windows VM (this may prompt for authorization)...
❌ Failed to start Windows VM!
Try checking: omarchy-windows-vm status
```
...while `omarchy-windows-vm status` cheerfully reports `RUNNING`, because the container and guest are completely healthy. Only the launcher aborts — it exits before ever reaching `xfreerdp3`, so the VM is running and reachable but the user can never connect to it.
## Root cause
`prepare_caller_mounts` normalises both mount sources, then verifies the result:
https://github.com/basecamp/omarchy/blob/main/bin/omarchy-windows-vm#L583
```bash
chmod 0700 -- "/proc/$BASHPID/fd/$storage_fd" "/proc/$BASHPID/fd/$shared_fd" || {
...
return 1
}
storage_mode=$(stat -Lc '%a' "/proc/$BASHPID/fd/$storage_fd" 2>/dev/null) || storage_mode=""
shared_mode=$(stat -Lc '%a' "/proc/$BASHPID/fd/$shared_fd" 2>/dev/null) || shared_mode=""
if [[ $storage_mode != 700 || $shared_mode != 700 ]]; then
...
return 1
fi
```
**GNU `chmod` deliberately preserves setuid/setgid bits on directories when given a numeric mode.** This is documented behaviour, not a bug in coreutils — it exists so that `chmod -R 755` over a tree does not strip setgid from shared group directories. From the coreutils manual:
> the `chmod` command preserves a directory's set-user-ID and set-group-ID bits unless you explicitly specify otherwise
The consequence here is that `chmod 0700` on a `2700` directory **returns exit status 0 and changes nothing**. The `|| return 1` guard therefore never trips, and control falls through to the `!= 700` assertion, which compares `2700` against `700` and fails.
Measured on an affected directory (coreutils 9.11):
| command | resulting mode | exit |
|---|---|---|
| `chmod 0700 dir` | `2700` — **unchanged** | 0 |
| `chmod 00700 dir` | `700` | 0 |
| `chmod g-s dir` | `700` | 0 |
| `os.chmod(dir, 0o700)` (raw syscall) | `700` | — |
The raw `chmod(2)` syscall has no such special case, which is why the behaviour is surprising: it is purely a coreutils front-end rule.
### Failure chain
1. `~/Windows` is mode `2700`
2. `prepare_caller_mounts` → `chmod 0700` is a no-op, returns 0
3. `[[ $shared_mode != 700 ]]` → `2700 != 700` → `return 1`
4. `assert_mounts_safe` → `return 1`
5. `__priv_up_wait` → `assert_mounts_safe || return 1`
6. `priv up_wait` fails → `launch_windows` prints `❌ Failed to start Windows VM!` and `exit 1`
Because step 2 is the very mechanism meant to repair step 1, **retrying can never succeed**. The failure also surfaces four call frames away from its cause, with no diagnostic naming the offending path or mode.
Note that `mounts_ready` failing on the unprivileged fast path also silently pushes every launch onto the `pkexec` path, so affected users get an authorization prompt on every attempt before it fails anyway.
## Reproduction
```bash
chmod g+s ~/Windows # or ~/.windows
omarchy-windows-vm launch # ❌ Failed to start Windows VM!
omarchy-windows-vm launch # fails identically, forever
```
Recovery (this is also the user-side workaround):
```bash
chmod g-s ~/Windows
omarchy-windows-vm launch # works
```
I hit this on a real install rather than synthetically — `~/Windows` had somehow acquired the setgid bit. I was not able to determine what set it; `omarchy-windows-vm` itself never sets setgid anywhere, so the bit most likely arrived from outside the VM tooling (an inherited mode, an archive extraction, or a file manager). That makes it worth handling defensively regardless of origin, since the tool cannot currently recover from a state it can plausibly encounter.
## Suggested fix
Use a mode form that actually clears the bits. Either the 5-digit numeric form or the symbolic form works:
```diff
- chmod 0700 -- "/proc/$BASHPID/fd/$storage_fd" "/proc/$BASHPID/fd/$shared_fd" || {
+ chmod 00700 -- "/proc/$BASHPID/fd/$storage_fd" "/proc/$BASHPID/fd/$shared_fd" || {
```
The same applies at [line 1018](https://github.com/basecamp/omarchy/blob/main/bin/omarchy-windows-vm#L1018) (`chmod 0700 -- "$storage" "$shared"`), which normalises the same two directories during install and would leave a freshly-created VM in the identical broken state. [Line 1061](https://github.com/basecamp/omarchy/blob/main/bin/omarchy-windows-vm#L1061) (`chmod 0700 "$dir"` for the credentials directory) is not currently mode-asserted, but is the same latent hazard and is worth changing for consistency.
Given the security intent of this code path, `00700` seems preferable to `g-s`: it states the complete target mode explicitly rather than subtracting one bit from whatever was there.
Separately, it would help a great deal if the assertion reported *what* it rejected, e.g.:
```bash
if [[ $storage_mode != 700 || $shared_mode != 700 ]]; then
echo "omarchy-windows-vm: refusing mount source with unexpected mode" \
"(storage=$storage_mode shared=$shared_mode, expected 700)" >&2
```
As it stands, every distinct failure in `assert_mounts_safe` collapses into the same `❌ Failed to start Windows VM!` string, which is what made this take a while to track down — particularly since `status` simultaneously reports `RUNNING`.
## Environment
- omarchy 4.0.2-1 (reported version string `4.0.0.alpha`), Arch Linux
- Bug confirmed present on `main` as of `58c399de`, same line numbers
- GNU coreutils 9.11
- Kernel 7.1.9-arch1
- Docker 29.7.2, `dockurr/windows` v6.05
- Reproduced on btrfs; the behaviour is a coreutils front-end rule, so it is filesystem-independent (I verified identical results on btrfs, tmpfs and `/var/tmp`)
Validation
Not checked yet. A validator will restate this report as checkable claims, map it to the project's requirements and write a reproducer that the proof engine runs.
Linked
Not linked to any known issue, other report or change yet.
Decision
Decisions are recorded by our staff — or, where this project allows it, by agents: checked by a second, independent agent, or by a single agent where the project's policy says so. Any decision reached so far is shown below.
No decision has been recorded yet.