Proof Portal

Project overview

Omarchy

ProbeLabs65 findings · 95 requirements

A 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.

Inbox
ReportR-4849GitHub issuePublicReceived

omarchy-windows-vm: launch/remove fail silently when ~/Windows has setgid (numeric chmod can't clear it since coreutils 9)

Reported by hyrujan · filed Sep 2, 2026Closed upstream on 2026-09-20 by bjarneo via an automated message, as a duplicate of #9334 (R-1173). GitHub close reason: completed.

Received and recorded verbatim. Nothing has been checked yet.

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

omarchy-windows-vm: launch/remove fail silently when ~/Windows has setgid (numeric chmod can't clear it since coreutils 9)revision 1 · captured 2026-10-04 12:10 UTC via poll

omarchy-windows-vm: launch and remove fail silently when ~/Windows carries a setgid bit (numeric chmod 0700 can't clear it since coreutils 9)

System details

  • CPU: Intel Core i5-8350U, GPU: Intel UHD Graphics 620 (Kaby Lake-R)
  • Omarchy 4.0.2-1 (VM originally installed under the previous major version, ~Aug 27)
  • Kernel 7.1.9-arch1-2, /home on btrfs subvolume @home
  • coreutils 9.11

What's wrong?

After updating to 4.0.2, both omarchy windows vm launch and omarchy windows vm remove fail:

Starting Windows VM (this may prompt for authorization)...
❌ Failed to start Windows VM!
   Try checking: omarchy-windows-vm status

remove stops with ❌ Windows VM removal stopped before user-side cleanup; inspect the VM data before retrying. omarchy windows vm status reports "container not found", so there is no obvious cause and no way out except manual surgery.

Root cause

The security-hardened rewrite binds ~/.windows and ~/Windows into root-owned anchors. In prepare_caller_mounts() (/usr/share/omarchy/bin/omarchy-windows-vm, the "Privacy is an explicit preflight step" block) the privileged path does:

chmod 0700 -- "/proc/$BASHPID/fd/$storage_fd" "/proc/$BASHPID/fd/$shared_fd"
...
if [[ $storage_mode != 700 || $shared_mode != 700 ]]; then
  ...
  return 1   # silent
fi

On my machine ~/Windows was mode 2700 — a setgid leftover from the older omarchy version / the dockurr/windows Samba share (the running container sets the shared dir to 2777, and a stopped one leaves the setgid bit). Since GNU coreutils 9.0, numeric chmod preserves set-user-ID/set-group-ID bits on directories unless explicitly specified (see man chmod: "For directories chmod preserves set-user-ID and set-group-ID bits unless you explicitly specify otherwise. To clear these bits for directories with a numeric mode requires an additional leading zero like 00755, leading minus like -6000, or leading equals like =755."). So the script's own hardening step can never clear the leftover bit: chmod 0700 succeeds (rc=0) but the very next stat still reads 2700, and the check fails with a silent return 1.

Both __priv_up_wait and __priv_remove funnel through assert_mounts_safe() → prepare_caller_mounts(), so launch and remove are broken together. The same latent chmod 0700 exists in the user-side prepare_user_mount_sources().

Minimal evidence of the chmod behavior:

$ mkdir t && chmod 2700 t
$ chmod 700 t && stat -c %a t        # coreutils, numeric: setgid SURVIVES
2700
$ chmod -s t && stat -c %a t
700
$ chmod 2700 t && chmod =700 t && stat -c %a t   # leading '=' does clear it
700
$ chmod 2700 t && python3 -c 'import os; os.chmod("t",0o700)' && stat -c %a t
700                                  # direct chmod(2) clears it; coreutils intentionally doesn't

Steps to reproduce

Windows VM installed on an earlier version and updated (or a ~/Windows created with the setgid bit), VM stopped:

chmod 2700 ~/Windows     # simulate the legacy/Samba setgid residue
omarchy windows vm launch   # ❌ Failed to start Windows VM!  (no reason printed)
omarchy windows vm remove   # ❌ ...stopped before user-side cleanup...
chmod -s ~/Windows       # clear setgid with something that actually clears it
omarchy windows vm launch   # works again

Tracing the privileged action shows the failure is silent — bash -x ends with storage_mode=700, shared_mode=2700, then an unlogged return 1 at the mode check.

Suggested fix

  1. Use a mode that actually clears the bits on directories: chmod =0700 (or 000700) instead of chmod 0700 in prepare_caller_mounts() and prepare_user_mount_sources().
  2. Don't fail silently: when the mode check (or assert_mounts_safe generally) bails, print an actionable message to stderr, e.g. omarchy-windows-vm: refusing to continue: $path has mode $storage_mode, expected 700. Right now up_wait/remove exit 1 with zero diagnostics and the user-facing wrapper only says "Failed to start Windows VM".

Side note

omarchy debug --no-sudo --print (as documented) now returns Unknown Omarchy command: omarchy debug --no-sudo --print; only the omarchy-debug binary works. Possibly a lost dispatcher route.

Diagnostics: /tmp/omarchy-debug.log attached (omarchy-debug --no-sudo --print on Omarchy 4.0.2).

View raw text
# omarchy-windows-vm: launch and remove fail silently when ~/Windows carries a setgid bit (numeric `chmod 0700` can't clear it since coreutils 9)

## System details

- CPU: Intel Core i5-8350U, GPU: Intel UHD Graphics 620 (Kaby Lake-R)
- Omarchy 4.0.2-1 (VM originally installed under the previous major version, ~Aug 27)
- Kernel 7.1.9-arch1-2, `/home` on btrfs subvolume `@home`
- coreutils 9.11

## What's wrong?

After updating to 4.0.2, both `omarchy windows vm launch` and `omarchy windows vm remove` fail:

```text
Starting Windows VM (this may prompt for authorization)...
❌ Failed to start Windows VM!
   Try checking: omarchy-windows-vm status
```

`remove` stops with `❌ Windows VM removal stopped before user-side cleanup; inspect the VM data before retrying.` `omarchy windows vm status` reports "container not found", so there is no obvious cause and no way out except manual surgery.

### Root cause

The security-hardened rewrite binds `~/.windows` and `~/Windows` into root-owned anchors. In `prepare_caller_mounts()` (`/usr/share/omarchy/bin/omarchy-windows-vm`, the "Privacy is an explicit preflight step" block) the privileged path does:

```bash
chmod 0700 -- "/proc/$BASHPID/fd/$storage_fd" "/proc/$BASHPID/fd/$shared_fd"
...
if [[ $storage_mode != 700 || $shared_mode != 700 ]]; then
  ...
  return 1   # silent
fi
```

On my machine `~/Windows` was mode **2700** — a setgid leftover from the older omarchy version / the `dockurr/windows` Samba share (the running container sets the shared dir to 2777, and a stopped one leaves the setgid bit). Since GNU coreutils 9.0, **numeric chmod preserves set-user-ID/set-group-ID bits on directories unless explicitly specified** (see `man chmod`: "For directories chmod preserves set-user-ID and set-group-ID bits unless you explicitly specify otherwise. To clear these bits for directories with a numeric mode requires an additional leading zero like 00755, leading minus like -6000, or leading equals like =755."). So the script's own hardening step can never clear the leftover bit: `chmod 0700` succeeds (rc=0) but the very next `stat` still reads `2700`, and the check fails with a silent `return 1`.

Both `__priv_up_wait` and `__priv_remove` funnel through `assert_mounts_safe()` → `prepare_caller_mounts()`, so launch and remove are broken together. The same latent `chmod 0700` exists in the user-side `prepare_user_mount_sources()`.

Minimal evidence of the chmod behavior:

```console
$ mkdir t && chmod 2700 t
$ chmod 700 t && stat -c %a t        # coreutils, numeric: setgid SURVIVES
2700
$ chmod -s t && stat -c %a t
700
$ chmod 2700 t && chmod =700 t && stat -c %a t   # leading '=' does clear it
700
$ chmod 2700 t && python3 -c 'import os; os.chmod("t",0o700)' && stat -c %a t
700                                  # direct chmod(2) clears it; coreutils intentionally doesn't
```

### Steps to reproduce

Windows VM installed on an earlier version and updated (or a `~/Windows` created with the setgid bit), VM stopped:

```bash
chmod 2700 ~/Windows     # simulate the legacy/Samba setgid residue
omarchy windows vm launch   # ❌ Failed to start Windows VM!  (no reason printed)
omarchy windows vm remove   # ❌ ...stopped before user-side cleanup...
chmod -s ~/Windows       # clear setgid with something that actually clears it
omarchy windows vm launch   # works again
```

Tracing the privileged action shows the failure is silent — `bash -x` ends with `storage_mode=700`, `shared_mode=2700`, then an unlogged `return 1` at the mode check.

### Suggested fix

1. Use a mode that actually clears the bits on directories: `chmod =0700` (or `000700`) instead of `chmod 0700` in `prepare_caller_mounts()` and `prepare_user_mount_sources()`.
2. Don't fail silently: when the mode check (or `assert_mounts_safe` generally) bails, print an actionable message to stderr, e.g. `omarchy-windows-vm: refusing to continue: $path has mode $storage_mode, expected 700`. Right now `up_wait`/`remove` exit 1 with zero diagnostics and the user-facing wrapper only says "Failed to start Windows VM".

### Side note

`omarchy debug --no-sudo --print` (as documented) now returns `Unknown Omarchy command: omarchy debug --no-sudo --print`; only the `omarchy-debug` binary works. Possibly a lost dispatcher route.

Diagnostics: `/tmp/omarchy-debug.log` attached (`omarchy-debug --no-sudo --print` on Omarchy 4.0.2).

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.