@samitouri / QOSAMI-WSL / commits / 5d097195

Fix potential service deadlock when plugin returns an error from OnVmStarted (#13569)

Blue committed Oct 8, 2025 at 15:40 UTC 5d097195faf0e2500863c86d50fbc10d2cd604dc
1 file changed +28 -24
src/windows/service/exe/LxssUserSession.cpp
+28 -24
@@ -2814,30 +2814,6 @@ void LxssUserSessionImpl::_CreateVm()
2814
2815 try
2816 {
2817 - auto callback = [this](auto Pid) {
2818 - // If the vm is currently being destroyed, the instance lock might be held
2819 - // while WslCoreVm's destructor is waiting on this thread.
2820 - // Cancel the call if the vm destruction is signaled.
2821 - // Note: This is safe because m_instanceLock is always initialized
2822 - // and because WslCoreVm's destructor waits for this thread, the session can't be gone
2823 - // until this callback completes.
2824 -
2825 - auto lock = m_instanceLock.try_lock();
2826 - while (!lock)
2827 - {
2828 - if (m_vmTerminating.wait(100))
2829 - {
2830 - return;
2831 - }
2832 - lock = m_instanceLock.try_lock();
2833 - }
2834 -
2835 - auto unlock = wil::scope_exit([&]() { m_instanceLock.unlock(); });
2836 - TerminateByClientIdLockHeld(Pid);
2837 - };
2838 -
2839 - m_utilityVm->RegisterCallbacks(std::bind(callback, _1), std::bind(s_VmTerminated, this, _1));
2840 -
2817 // Mount disks after the system distro vhd is mounted in case filesystem detection is needed.
2818 _LoadDiskMounts();
2819
@@ -2869,6 +2845,34 @@ void LxssUserSessionImpl::_CreateVm()
2845 _VmTerminate();
2846 throw;
2847 }
2848 +
2849 + auto callback = [this](auto Pid) {
2850 + // If the vm is currently being destroyed, the instance lock might be held
2851 + // while WslCoreVm's destructor is waiting on this thread.
2852 + // Cancel the call if the vm destruction is signaled.
2853 + // Note: This is safe because m_instanceLock is always initialized
2854 + // and because WslCoreVm's destructor waits for this thread, the session can't be gone
2855 + // until this callback completes.
2856 +
2857 + auto lock = m_instanceLock.try_lock();
2858 + while (!lock)
2859 + {
2860 + if (m_vmTerminating.wait(100))
2861 + {
2862 + return;
2863 + }
2864 + lock = m_instanceLock.try_lock();
2865 + }
2866 +
2867 + auto unlock = wil::scope_exit([&]() { m_instanceLock.unlock(); });
2868 + TerminateByClientIdLockHeld(Pid);
2869 + };
2870 +
2871 + // N.B. The callbacks must be registered outside of the above try/catch.
2872 + // Otherwise if an exception is thrown, calling _VmTerminate() will trigger the 's_VmTerminated' termination callback
2873 + // Which can deadlock since this thread holds the instance lock and HCS can block until the VM termination callback returns before deleting the VM.
2874 +
2875 + m_utilityVm->RegisterCallbacks(std::bind(callback, _1), std::bind(s_VmTerminated, this, _1));
2876 }
2877
2878 _VmCheckIdle();