Plugin DLLs are now loaded in isolated wslpluginhost.exe processes
instead of directly in wslservice.exe via LoadLibrary. This prevents
a buggy or malicious plugin from crashing the WSL service.
Architecture:
- New IWslPluginHost/IWslPluginHostCallback COM interfaces
(WslPluginHost.idl) for cross-process plugin lifecycle management
- New wslpluginhost.exe: COM local server (REGCLS_SINGLEUSE), one
per plugin, loads the plugin DLL and dispatches notifications
- Refactored PluginManager: CoCreateInstance replaces LoadLibrary,
PluginError returned via [out] parameter, crash recovery via
IsHostCrash() detecting RPC_E_DISCONNECTED/SERVER_DIED
Callback safety:
- Plugin callbacks (MountFolder, ExecuteBinary) arrive on a different
COM RPC thread and use std::shared_lock(m_callbackLock) instead of
m_instanceLock to avoid re-entrancy deadlocks
- _VmTerminate takes exclusive m_callbackLock before destroying the
VM, blocking until in-flight callbacks complete
- Lock ordering: m_instanceLock -> m_callbackLock (never reverse)
- All writes to m_runningInstances take m_callbackLock exclusive to
prevent data races with concurrent callback reads
Security:
- COM AppID with SYSTEM-only launch/access permissions
- Plugin signature validation (ValidateFileSignature) keeps the file
handle open until after LoadLibrary to prevent TOCTOU attacks
- Plugin host processes use minimal access rights for handles
Process lifecycle:
- Plugin hosts added to a job object with KILL_ON_JOB_CLOSE for
automatic cleanup if wslservice exits
- g_pluginHost is process-wide (REGCLS_SINGLEUSE guarantees one
plugin per process), nulled on destruction to prevent UAF
- std::call_once for thread-safe initialization and job creation
Packaging:
- WslPluginHost.idl compiled into existing wslserviceproxystub.dll
- MSI: COM class/interface registration, AppID security, proxy/stub
- wslpluginhost.exe added to build/signing pipeline, WER crash dump
list, LSP registration, and test validation
Plugins are not loaded for WSL1-only sessions since all plugin hooks
require a WSL2 VM. WslPluginApi.h is unchanged - existing plugin DLLs
work unmodified.
Cherry-pick WSL1/WSL2 test changes from 9c4dba91 (feature/wsl-for-apps).
Replace runtime WSL1_TEST_ONLY()/WSL2_TEST_ONLY() skip macros with
WSL1_TEST_METHOD()/WSL2_TEST_METHOD() TAEF metadata macros. This moves
version filtering to the test runner level via /select: queries, so
inapplicable tests are excluded entirely instead of appearing as skipped.
Updated files:
- test/windows/Common.h: New macros + removed old skip macros
- test/windows/*.cpp: Converted all test methods
- tools/test/run-tests.ps1: Auto-add /select: when no user filter
- cloudtest/TestGroup.xml.in: Add version filter to TAEF args
- test/README.md: Document new macros
Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Many Microsoft employees have contributed to the Windows Subsystem for Linux, this commit is the result of their work since 2016.
The entire history of the Windows Subsystem for Linux can't be shared here, but here's an overview of WSL's history after it moved to it own repository in 2021:
Number of commits on the main branch: 2930
Number of contributors: 31
Head over https://github.com/microsoft/WSL/releases for a more detailed history of the features added to WSL since 2021.