Skip to content

disk: a copied disk keeps WSL 3.0.2's user-only permissions - #120

Merged
zcsizmadia merged 2 commits into
mainfrom
disk-copy-dacl-and-wsl3-errors
Oct 24, 2026
Merged

zcsizmadia merged 2 commits into
mainfrom
disk-copy-dacl-and-wsl3-errors

Conversation

@zcsizmadia

@zcsizmadia zcsizmadia commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Three things from reading the WSL 3.0.1 to 3.0.4 releases and the issues filed since 3.0 went GA.

A copied disk keeps its user-only permissions

WSL 3.0.2 (microsoft/WSL#41678) creates each distribution disk with a protected access list: the user, Administrators and the VM. CopySparse created its destination with default security, so disk move across volumes and disk snapshot gave the copy whatever its new folder allowed. It now copies a protected list onto the new file. An inherited list (a disk from an older WSL) still inherits, as before. A rename within one volume never had the problem.

Measured, on WSL 3.0.3:

  • A distribution imported on 3.0.3 gets D:PAI(A;;FA;;;BA)(A;;FA;;;<user>)(A;;FA;;;<VM SID>)(A;;FA;;;<capability SID>).
  • TestCopySparseKeepsAProtectedAccessList fails with the fix reverted. The copy came out as the temp folder's inherited list, including modify access for another local account.
  • Live, with the built binary on that imported distribution:
    • disk snapshot wrote D:P(A;;FA;;;BA)(A;;FA;;;<user>) into a folder that would otherwise have given it inherited entries.
    • disk move to a folder on D: kept the protected list. That folder gives Everyone full control by inheritance, which is what the copy would have had.
  • The move then failed its start check, which is expected: the throwaway distribution has no init. Rollback restored the registration but could not delete the copy, because the VM still held it. That gap exists before this change; it is not addressed here.

wsl --list --running --quiet comment corrected

With nothing running, it exits 0 and prints nothing. I measured that on 3.0.3, and WslClient.cpp returns -1 only without --quiet. The old comment said otherwise. The code's behaviour was already right; the comment now also notes that this makes the truncated output in microsoft/WSL#41937 (security software ending wsl.exe before it flushed) impossible to tell apart from "none".

Error dictionary

  • WSAETIMEDOUT / 0x8007274C: three causes. The 3.0.3 new-session failure (#42029, #42006), after sleep (#41830), and mirrored mode (#42034).
  • WSAENOBUFS: after Modern Standby (#41777).
  • ERROR_INVALID_DATA: nested virtualization lost after KB5127648 on AMD hosts (#41917, warning added in #41942).
  • HCS_E_HYPERV_NOT_INSTALLED: split into causes. The new one is damaged Windows components (#41994).

doctor explain "Wsl/Service/0x8007274c" and doctor explain 0x8007000d were run against the built binary and print the new causes.

Go 1.27.3

govulncheck now fails on 1.27.1 for every branch: crypto/x509 (GO-2026-6809, fixed in 1.27.3) and net/http and http2 (GO-2026-6611 to 6617, fixed in 1.27.2). go.mod moves to 1.27.3; the full suite passes locally on it.

WSL 3.0.2 (microsoft/WSL#41678) creates each distribution disk with a
protected access list: the user, Administrators and the VM. CopySparse
created its destination with default security, so disk move across volumes
and disk snapshot gave the copy whatever its new folder allowed. Copy a
protected list onto the new file; let an inherited one inherit as before.

The comment on wsl --list --running --quiet was wrong: with nothing running
it exits 0 and prints nothing (measured on 3.0.3, and WslClient.cpp only
returns -1 without --quiet). Say so, and that this makes
microsoft/WSL#41937's truncated output indistinguishable from "none".

errors.json: WSAETIMEDOUT (0x8007274C), WSAENOBUFS and ERROR_INVALID_DATA
get explanations from the WSL 3.0.x issues, and HCS_E_HYPERV_NOT_INSTALLED
gets the damaged-components cause.
…ture back

govulncheck fails on 1.27.1: crypto/x509 (GO-2026-6809, fixed in 1.27.3)
and net/http and its http2 (GO-2026-6611 to 6617, fixed in 1.27.2).

The protected-list test matched the user's SID as a string; on the CI runner
the account is the built-in Administrator and SDDL prints it as LA. Check
the fixture is protected with one entry instead.
@zcsizmadia
zcsizmadia merged commit b9ab810 into main Oct 24, 2026
4 checks passed
@zcsizmadia
zcsizmadia deleted the disk-copy-dacl-and-wsl3-errors branch October 24, 2026 23:32
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