WSLService can become unresponsive when init transactions wait indefinitely under session locks
Summary
When the Linux guest stops responding, process launches can wait indefinitely. A concurrent shutdown can then block behind the same instance lock while holding the session lock, causing distribution enumeration, shutdown, and service termination to stop progressing.
Two request/response operations and one send operation in WslCoreInstance use the infinite default SocketChannel timeout while holding locks needed by other session operations.
Impact
If the guest remains connected but stops responding, the affected operation can wait indefinitely while holding locks needed by shutdown and other session operations. This can prevent distribution enumeration, shutdown, and service termination from progressing.
Code analysis
On Windows, SocketChannel::DefaultSocketTimeout is INFINITE.
The following operations omitted the existing m_socketTimeout value:
sessionLeader->GetChannel().Transaction<LX_INIT_CREATE_PROCESS_UTILITY_VM>(messageSpan)
m_initChannel->GetChannel().StartTransaction()
The affected paths are:
WslCoreInstance::CreateLxProcess() while holding WslCoreInstance::m_lock;
WslCoreInstance::Initialize() while holding m_lock, with its caller also holding LxssUserSessionImpl::m_instanceLock;
WslCoreInstance::UpdateTimezone() while holding the channel lock, with its caller holding m_instanceLock.
RequestStop() and Stop() also require m_lock. A guest that does not answer a process-creation transaction can therefore prevent the shutdown path from acquiring the lock and progressing.
The same class already uses m_socketTimeout for comparable init operations. The value comes from DistributionStartTimeout, which defaults to 60 seconds and is configurable.
Expected behavior
A non-responsive guest may cause the individual operation to fail, but it must not leave WSLService, shutdown, enumeration, or unrelated session operations blocked indefinitely.
Proposed change
Pass m_socketTimeout to all three transactions:
Transaction<LX_INIT_CREATE_PROCESS_UTILITY_VM>(messageSpan, nullptr, m_socketTimeout)
StartTransaction(m_socketTimeout)
This applies the timeout policy already used by the surrounding code and does not introduce a new timeout value.
Tests
The added unit tests verify that:
- the peer receives the transaction request;
- a peer that remains connected without responding produces
HRESULT_FROM_WIN32(ERROR_TIMEOUT) within a bounded interval;
- a valid response received before the deadline succeeds normally.
These tests validate SocketChannel::Transaction timeout propagation and behavior. They do not constitute a complete reproduction using a real WslCoreInstance or Linux guest.
WSLService can become unresponsive when init transactions wait indefinitely under session locks
Summary
When the Linux guest stops responding, process launches can wait indefinitely. A concurrent shutdown can then block behind the same instance lock while holding the session lock, causing distribution enumeration, shutdown, and service termination to stop progressing.
Two request/response operations and one send operation in
WslCoreInstanceuse the infinite defaultSocketChanneltimeout while holding locks needed by other session operations.Impact
If the guest remains connected but stops responding, the affected operation can wait indefinitely while holding locks needed by shutdown and other session operations. This can prevent distribution enumeration, shutdown, and service termination from progressing.
Code analysis
On Windows,
SocketChannel::DefaultSocketTimeoutisINFINITE.The following operations omitted the existing
m_socketTimeoutvalue:sessionLeader->GetChannel().Transaction<LX_INIT_CREATE_PROCESS_UTILITY_VM>(messageSpan) m_initChannel->GetChannel().StartTransaction()The affected paths are:
WslCoreInstance::CreateLxProcess()while holdingWslCoreInstance::m_lock;WslCoreInstance::Initialize()while holdingm_lock, with its caller also holdingLxssUserSessionImpl::m_instanceLock;WslCoreInstance::UpdateTimezone()while holding the channel lock, with its caller holdingm_instanceLock.RequestStop()andStop()also requirem_lock. A guest that does not answer a process-creation transaction can therefore prevent the shutdown path from acquiring the lock and progressing.The same class already uses
m_socketTimeoutfor comparable init operations. The value comes fromDistributionStartTimeout, which defaults to 60 seconds and is configurable.Expected behavior
A non-responsive guest may cause the individual operation to fail, but it must not leave
WSLService, shutdown, enumeration, or unrelated session operations blocked indefinitely.Proposed change
Pass
m_socketTimeoutto all three transactions:This applies the timeout policy already used by the surrounding code and does not introduce a new timeout value.
Tests
The added unit tests verify that:
HRESULT_FROM_WIN32(ERROR_TIMEOUT)within a bounded interval;These tests validate
SocketChannel::Transactiontimeout propagation and behavior. They do not constitute a complete reproduction using a realWslCoreInstanceor Linux guest.