microsoft / microsoft/WSL

WSLService can become unresponsive when init transactions wait indefinitely under session locks

Open
#41,384 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug needs-investigation wsl2
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.