Skip to content

Commit ed98200

Browse files
author
Ben Hillis
committed
fix potentially race
1 parent 77c3483 commit ed98200

File tree

1 file changed

+19
-7
lines changed

1 file changed

+19
-7
lines changed

src/windows/service/exe/LxssUserSession.cpp

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3582,14 +3582,19 @@ bool LxssUserSessionImpl::_TerminateInstanceInternal(_In_ LPCGUID DistroGuid, _I
35823582
m_pluginManager.OnDistributionStopping(&m_session, wslcoreInstance->DistributionInformation());
35833583
}
35843584

3585-
instance->second->Stop();
3586-
3587-
const auto clientId = instance->second->GetClientId();
3588-
35893585
m_lifetimeManager.RemoveCallback(clientKey);
35903586

3587+
// Stop the instance and remove it from m_runningInstances atomically
3588+
// under m_callbackLock. This prevents plugin callbacks (which hold
3589+
// m_callbackLock shared) from finding a stopped-but-still-listed
3590+
// instance between Stop() and erase.
3591+
ULONG clientId;
35913592
{
35923593
std::unique_lock callbackLock(m_callbackLock);
3594+
3595+
instance->second->Stop();
3596+
clientId = instance->second->GetClientId();
3597+
35933598
{
35943599
auto lock = m_terminatedInstanceLock.lock_exclusive();
35953600
m_terminatedInstances.push_back(std::move(instance->second));
@@ -3647,9 +3652,16 @@ HRESULT LxssUserSessionImpl::CreateLinuxProcess(_In_opt_ const GUID* Distro, _In
36473652
}
36483653
else
36493654
{
3650-
const auto distro = _RunningInstance(Distro);
3651-
THROW_HR_IF(WSL_E_VM_MODE_INVALID_STATE, !distro);
3652-
3655+
// Look up the running instance directly instead of calling _RunningInstance,
3656+
// which accesses m_lockedDistributions (guarded only by m_instanceLock).
3657+
// m_runningInstances is safe to read under m_callbackLock (shared).
3658+
// The _EnsureNotLocked check is unnecessary here: _ConversionBegin removes
3659+
// a distribution from m_runningInstances before adding it to m_lockedDistributions,
3660+
// so a locked distribution will never be found in this lookup.
3661+
const auto instance = m_runningInstances.find(*Distro);
3662+
THROW_HR_IF(WSL_E_VM_MODE_INVALID_STATE, instance == m_runningInstances.end());
3663+
3664+
const auto distro = instance->second;
36533665
const auto wsl2Distro = dynamic_cast<WslCoreInstance*>(distro.get());
36543666
THROW_HR_IF(WSL_E_WSL2_NEEDED, !wsl2Distro);
36553667

0 commit comments

Comments
 (0)