Skip to content

doctor: KVM001, BIN001 and NET005 from the WSL 3.0.x issues - #121

Merged
zcsizmadia merged 2 commits into
mainfrom
doctor-nested-binfmt-ports
Oct 25, 2026
Merged

zcsizmadia merged 2 commits into
mainfrom
doctor-nested-binfmt-ports

Conversation

@zcsizmadia

Copy link
Copy Markdown
Contributor

Checks 4 to 6 from the WSL 3.0.x survey. Each is read-only, and none starts a distribution: the guest-side facts come from one that is already running, or the check is skipped.

KVM001: nested virtualization reaches the VM

WSL drops nested virtualization when the host can't provide it. The October 2026 cumulative update (KB5127648, builds ending .9711) made it unable to on AMD hosts, and up to 3.0.3 WSL said nothing (microsoft/WSL#41917; 3.0.4 adds a warning, #41942).

The check works out whether WSL will ask for nested virtualization the way WslCoreConfig does: never on Windows 10, on by default on Windows 11 amd64, off on arm64, and off under safeMode or policy AllowNestedVirtualization=0. It then reads /dev/kvm, vmx/svm and vendor_id in the VM. AMD on build ≥ 26100 at revision ≥ 9711 gets its own finding.

BIN001: Windows programs launch from Linux

This reads the kernel's binfmt_misc table, which is shared by the whole VM (ProtectBinfmtStatus in WSL's init). It fails if WSLInterop is missing or disabled, and warns if another enabled handler claims MZ at offset 0 or .exe (microsoft/WSL#41739). If the distribution's wsl.conf turns interop off, that's reported as OK.

NET005: mirrored networking can reserve its port range

This only runs with networkingMode=mirrored. WSL asks HNS for one contiguous run of 4096 TCP and UDP ports. Up to 3.0.3 a refusal means 0x8007054f and no network; from 3.0.4 it halves the request down to 512 (#41880). The check computes the longest run of each dynamic range (from netsh) that no exclusion covers. HNS's choice is undocumented, and the check says so: it measures the fragmentation #41812 traced, and can't see ports that are merely in use.

Verified

  • Live, with the built binary, WSL 3.0.3, Windows 10:
    • The VM facts were read from Ubuntu: Intel, no KVM, binfmt shows WSLInterop and python3.14.
    • BIN001 was OK.
    • I registered a throwaway handler :wkfake:M::MZ::/bin/false:. cmd.exe launched from Linux then ran under /bin/false, and BIN001 warned and named it. After echo -1, interop worked again.
    • I removed WSLInterop and BIN001 failed with "is missing". I then restored it with WSL's own registration string, and cmd.exe ran again.
    • KVM001 said "never on Windows 10". NET005 skipped, because networking here is NAT.
  • Not driven live: KVM001's AMD/.9711 path and NET005's warn and fail paths. They need Windows 11 on AMD with the October update, and a mirrored host with a fragmented range. They're covered by table tests on the measured shapes.
  • Mutation check: each key condition (the AMD/.9711 match, the MZ/.exe match, the disabled-entry check, the free-run computation, the 3.0.4 retry gate, the entry parser, the asterisked exclusion line) was broken in turn, and a test failed each time.
  • The fixtures are the real script output from Ubuntu and real netsh output from this machine.

KVM001: nested virtualization asked for (the Windows 11 amd64 default, or
.wslconfig) but no /dev/kvm and no vmx/svm in the VM. Names the October 2026
update that breaks it on AMD (KB5127648, builds .9711, microsoft/WSL#41917).
Mirrors WslCoreConfig: never on Windows 10, off by default on arm64, off
under safeMode or policy AllowNestedVirtualization=0.

BIN001: WSLInterop missing or disabled in binfmt_misc, or another enabled
handler claiming "MZ" or .exe (mono, wine; microsoft/WSL#41739). The table is
the kernel's, so it is read once.

NET005: with mirrored networking, the longest run of the TCP and UDP dynamic
port ranges that no exclusion covers, against the 4096 ports WSL reserves
(512 at least from 3.0.4, microsoft/WSL#41880). HNS's choice is undocumented;
this measures the fragmentation microsoft/WSL#41812 traced.

Collected: env.VM from one already-running WSL 2 distribution (never starts
one), and netsh's dynamic and excluded port ranges.
@zcsizmadia
zcsizmadia merged commit b1c2524 into main Oct 25, 2026
4 checks passed
@zcsizmadia
zcsizmadia deleted the doctor-nested-binfmt-ports branch October 25, 2026 02:42
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