Fix incorrect timeout causing WSL1 OOBE to fail if the OOBE process takes longer than 30 seconds (#13517)
* Fix incorrect timeout causing WSL1 OOBE to fail if the OOBE process takes longer than 30 seconds * Pass the timeout to WaitForMessage
Blue committed
Sep 25, 2025 at 02:58 UTC
332efe1a8dfdcb3d18a2d37e195cdec014f7d43f
3 files changed
+10
-7
src/windows/common/LxssMessagePort.cpp
+4
-5
@@ -19,7 +19,6 @@ Abstract:
19
// Defines.
20
21
#define LAUNCH_PROCESS_DEFAULT_BUFFER_SIZE 1024
22
-#define LAUNCH_PROCESS_DEFAULT_TIMEOUT_MS 30000
22
23
LxssMessagePort::LxssMessagePort(_In_ HANDLE MessagePort) : m_messagePort(MessagePort), m_messageEvent(wil::EventOptions::None)
24
{
@@ -52,7 +51,7 @@ std::shared_ptr<LxssPort> LxssMessagePort::CreateSessionLeader(_In_ HANDLE Clien
51
LX_INIT_CREATE_SESSION Message{{LxInitMessageCreateSession, sizeof(Message)}, MarshalId};
52
53
Send(&Message, sizeof(Message));
55
- auto LocalMessagePort = m_serverPort->WaitForConnection(LAUNCH_PROCESS_DEFAULT_TIMEOUT_MS);
54
+ auto LocalMessagePort = m_serverPort->WaitForConnection(c_defaultMessageTimeout);
55
ReleaseConsole.release();
56
return LocalMessagePort;
57
}
@@ -156,7 +155,7 @@ void LxssMessagePort::Receive(_Out_writes_bytes_(Length) PVOID Buffer, _In_ ULON
155
return;
156
}
157
159
-std::vector<gsl::byte> LxssMessagePort::Receive()
158
+std::vector<gsl::byte> LxssMessagePort::Receive(DWORD Timeout)
159
{
160
IO_STATUS_BLOCK IoStatus;
161
std::vector<gsl::byte> Message;
@@ -170,7 +169,7 @@ std::vector<gsl::byte> LxssMessagePort::Receive()
169
170
if (Status == STATUS_PENDING)
171
{
173
- WaitForMessage(&IoStatus);
172
+ WaitForMessage(&IoStatus, Timeout);
173
Status = IoStatus.Status;
174
SizeReceived = static_cast<ULONG>(IoStatus.Information);
175
}
@@ -274,7 +273,7 @@ wil::unique_handle LxssMessagePort::UnmarshalVfsFile(_In_ LXBUS_IPC_HANDLE_ID Vf
273
274
void LxssMessagePort::WaitForMessage(_In_ PIO_STATUS_BLOCK IoStatus, _In_ DWORD Timeout) const
275
{
277
- const DWORD WaitStatus = WaitForSingleObject(m_messageEvent.get(), LAUNCH_PROCESS_DEFAULT_TIMEOUT_MS);
276
+ const DWORD WaitStatus = WaitForSingleObject(m_messageEvent.get(), Timeout);
277
if (WaitStatus == WAIT_TIMEOUT)
278
{
279
IO_STATUS_BLOCK IoStatusCancel;
src/windows/common/LxssMessagePort.h
+3
-1
@@ -21,6 +21,8 @@ class LxssServerPort;
21
class LxssMessagePort : public LxssPort
22
{
23
public:
24
+ static inline DWORD c_defaultMessageTimeout = 30000;
25
+
26
LxssMessagePort(_In_ HANDLE MessagePort);
27
LxssMessagePort(_In_ LxssMessagePort&& Source);
28
LxssMessagePort(_In_ std::unique_ptr<LxssMessagePort>&& SourcePointer);
@@ -46,7 +48,7 @@ public:
48
LXBUS_IPC_PROCESS_ID
49
MarshalProcess(_In_ HANDLE ProcessHandle, _In_ bool TerminateOnClose) const;
50
49
- std::vector<gsl::byte> Receive();
51
+ std::vector<gsl::byte> Receive(DWORD Timeout = c_defaultMessageTimeout);
52
53
void ReleaseConsole(_In_ LXBUS_IPC_CONSOLE_ID ConsoleId) const;
54
src/windows/service/exe/LxssInstance.cpp
+3
-1
@@ -551,7 +551,9 @@ wil::unique_handle LxssInstance::_CreateLxProcess(
551
m_oobeThread = std::thread([this, OobeMessagePort = std::move(OobeMessagePort), registration = std::move(registration)]() mutable {
552
try
553
{
554
- auto Message = OobeMessagePort->Receive();
554
+ // N.B. The LX_INIT_OOBE_RESULT message is only sent once the OOBE process completes, which might be waiting on user input.
555
+ // Do no set a timeout here otherwise the OOBE flow will fail if the OOBE process takes longer than expected.
556
+ auto Message = OobeMessagePort->Receive(INFINITE);
557
auto* OobeResult = gslhelpers::try_get_struct<LX_INIT_OOBE_RESULT>(gsl::make_span(Message));
558
THROW_HR_IF(E_INVALIDARG, !OobeResult || (OobeResult->Header.MessageType != LxInitOobeResult));
559