Skip to content

Fix the Windows VM refusing to start after its first launch - #10338

Open
shilai-li wants to merge 1 commit into
omacom:quattrofrom
shilai-li:fix/windows-vm-shared-setgid
Open

Fix the Windows VM refusing to start after its first launch#10338
shilai-li wants to merge 1 commit into
omacom:quattrofrom
shilai-li:fix/windows-vm-shared-setgid

Conversation

@shilai-li

Copy link
Copy Markdown

Problem

The Windows VM installs and runs once, then every launch after that fails with:

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

Launched from the app icon, windows-vm.desktop has Terminal=false, so even that message goes nowhere — clicking Windows does nothing at all, with no notification and nothing in the journal beyond the scope starting and exiting.

Cause

prepare_caller_mounts hardens both bind sources to 0700 and then verifies they are exactly 700 (bin/omarchy-windows-vm:583):

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

The container's Samba layer chmods the shared folder to 2777 so it can serve it to the guest (chmod 2777 "$dir" in /run/samba.sh in dockurr/windows). /shared is a bind of the caller's ~/Windows, so that setgid bit lands on the host directory.

A numeric mode below 010000 leaves a directory's setuid and setgid bits untouched. So the hardening step turns 2777 into 2700 rather than 700, and the check immediately below it then rejects the source the script has just tried to fix. On coreutils 9.11:

starting from 6777:
  chmod 0700       -> 6700   (no effect)
  chmod 700        -> 6700   (no effect)
  chmod u=rwx,go=  -> 6700   (symbolic alone does not clear s either)
  chmod 00700      -> 700
  chmod u=rwx,go=,a-s -> 700

The first launch works because Samba has not dirtied the folder yet. Every launch after it fails, and it fails before reaching Docker at all, which is why nothing shows up in docker ps -a or the daemon log.

prepare_user_mount_sources hardens the same two directories on the install path (:1018) and has the same defect.

Fix

Spell both chmods u=rwx,go=,a-s so the hardening can actually reach the state its own check demands. chmod 00700 also works, but only because the GNU carve-out keys on the length of the octal string rather than its value — it reads like a typo and invites being "cleaned up" straight back into the bug, so the symbolic form seemed worth the few extra characters.

Also give the two silent return 1 exits something to say. The mode check is still worth keeping as defence in depth: it now catches a source on a filesystem that ignores chmod rather than failing mute.

Verification

On an affected machine, ~/Windows at 2700 going in, running the privileged bring-up directly:

script exit ~/Windows after
packaged /usr/bin/omarchy-windows-vm 1 (silent, 5s, never reaches Docker) 2700
this branch 0 700

Full launch cycle through the app icon then works repeatedly, where before it succeeded exactly once per fresh install.

test/shell run before and after: 6 pre-existing failures, identical with and without this change (bar-icon-geometry, bin-style, config, snapper, unowned-system-paths, windows-vm-mount-boundary).

Worth a separate look: windows-vm-mount-boundary-test.sh cannot pass on a machine where the VM has been launched since boot. It builds a fake uid-1000 home under unshare --user --mount, but that namespace inherits the real binds at /var/lib/omarchy/windows/mounts/users/1000/*, which point at the actual home, so mounted_leaf_matches rejects them. Mounts inherited into a user namespace are locked, so the test cannot unmount them to isolate itself either. Not touched here.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WB1hMW2yRN5tHRsVKon9UG

The VM would install and run once, then fail every subsequent launch with
"Failed to start Windows VM!" and no further explanation.

prepare_caller_mounts hardens both bind sources to 0700 and then verifies
they are exactly 700. The container's Samba layer chmods the shared folder
to 2777 so it can serve it to the guest, and that lands on the caller's
~/Windows through the bind. Numeric modes below 010000 leave a directory's
setuid and setgid bits untouched, so the hardening step turned 2777 into
2700 rather than 700 and the verification below it then rejected the source
the script had just tried to fix. The first launch worked because Samba had
not dirtied the folder yet; every launch after it failed.

Spell both chmods symbolically with an explicit a-s so the hardening can
actually reach the state its own check demands, and say something on the way
out of the two silent exits, which is why this presented as a launcher that
did nothing at all.
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