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
This commit is contained in:
Blue 2025-09-25 02:58:39 +00:00 committed by GitHub
parent 4bba074bd2
commit 332efe1a8d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 10 additions and 7 deletions

View File

@ -19,7 +19,6 @@ Abstract:
// Defines.
#define LAUNCH_PROCESS_DEFAULT_BUFFER_SIZE 1024
#define LAUNCH_PROCESS_DEFAULT_TIMEOUT_MS 30000
LxssMessagePort::LxssMessagePort(_In_ HANDLE MessagePort) : m_messagePort(MessagePort), m_messageEvent(wil::EventOptions::None)
{
@ -52,7 +51,7 @@ std::shared_ptr<LxssPort> LxssMessagePort::CreateSessionLeader(_In_ HANDLE Clien
LX_INIT_CREATE_SESSION Message{{LxInitMessageCreateSession, sizeof(Message)}, MarshalId};
Send(&Message, sizeof(Message));
auto LocalMessagePort = m_serverPort->WaitForConnection(LAUNCH_PROCESS_DEFAULT_TIMEOUT_MS);
auto LocalMessagePort = m_serverPort->WaitForConnection(c_defaultMessageTimeout);
ReleaseConsole.release();
return LocalMessagePort;
}
@ -156,7 +155,7 @@ void LxssMessagePort::Receive(_Out_writes_bytes_(Length) PVOID Buffer, _In_ ULON
return;
}
std::vector<gsl::byte> LxssMessagePort::Receive()
std::vector<gsl::byte> LxssMessagePort::Receive(DWORD Timeout)
{
IO_STATUS_BLOCK IoStatus;
std::vector<gsl::byte> Message;
@ -170,7 +169,7 @@ std::vector<gsl::byte> LxssMessagePort::Receive()
if (Status == STATUS_PENDING)
{
WaitForMessage(&IoStatus);
WaitForMessage(&IoStatus, Timeout);
Status = IoStatus.Status;
SizeReceived = static_cast<ULONG>(IoStatus.Information);
}
@ -274,7 +273,7 @@ wil::unique_handle LxssMessagePort::UnmarshalVfsFile(_In_ LXBUS_IPC_HANDLE_ID Vf
void LxssMessagePort::WaitForMessage(_In_ PIO_STATUS_BLOCK IoStatus, _In_ DWORD Timeout) const
{
const DWORD WaitStatus = WaitForSingleObject(m_messageEvent.get(), LAUNCH_PROCESS_DEFAULT_TIMEOUT_MS);
const DWORD WaitStatus = WaitForSingleObject(m_messageEvent.get(), Timeout);
if (WaitStatus == WAIT_TIMEOUT)
{
IO_STATUS_BLOCK IoStatusCancel;

View File

@ -21,6 +21,8 @@ class LxssServerPort;
class LxssMessagePort : public LxssPort
{
public:
static inline DWORD c_defaultMessageTimeout = 30000;
LxssMessagePort(_In_ HANDLE MessagePort);
LxssMessagePort(_In_ LxssMessagePort&& Source);
LxssMessagePort(_In_ std::unique_ptr<LxssMessagePort>&& SourcePointer);
@ -46,7 +48,7 @@ public:
LXBUS_IPC_PROCESS_ID
MarshalProcess(_In_ HANDLE ProcessHandle, _In_ bool TerminateOnClose) const;
std::vector<gsl::byte> Receive();
std::vector<gsl::byte> Receive(DWORD Timeout = c_defaultMessageTimeout);
void ReleaseConsole(_In_ LXBUS_IPC_CONSOLE_ID ConsoleId) const;

View File

@ -551,7 +551,9 @@ wil::unique_handle LxssInstance::_CreateLxProcess(
m_oobeThread = std::thread([this, OobeMessagePort = std::move(OobeMessagePort), registration = std::move(registration)]() mutable {
try
{
auto Message = OobeMessagePort->Receive();
// N.B. The LX_INIT_OOBE_RESULT message is only sent once the OOBE process completes, which might be waiting on user input.
// Do no set a timeout here otherwise the OOBE flow will fail if the OOBE process takes longer than expected.
auto Message = OobeMessagePort->Receive(INFINITE);
auto* OobeResult = gslhelpers::try_get_struct<LX_INIT_OOBE_RESULT>(gsl::make_span(Message));
THROW_HR_IF(E_INVALIDARG, !OobeResult || (OobeResult->Header.MessageType != LxInitOobeResult));