WSLService can become unresponsive when init transactions wait indefinitely under session locks
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 33.7k
- Forks
- 1.8k
- Avg merge
- 3d 17h
- Merged PRs (30d)
- 116
Description
# 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:
```cpp
sessionLeader->GetChannel().Transaction(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:
```cpp
Transaction(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.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with WslCoreInstance::CreateLxProcess(), Initialize(), and UpdateTimezone(), then compare their SocketChannel transactions with nearby uses of m_socketTimeout. Verify the three transactions pass the configured timeout, and run the added unit tests to confirm bounded ERROR_TIMEOUT failures and successful responses received before the deadline.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- operating-systems
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 74/100