From 57280f6b5b21790c70e493d49bbae7fd848fc5c1 Mon Sep 17 00:00:00 2001 From: Feng Wang Date: Thu, 16 Jul 2026 17:41:02 +0800 Subject: [PATCH 01/10] Put revert before set owner --- src/windows/service/exe/LxssUserSession.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/windows/service/exe/LxssUserSession.cpp b/src/windows/service/exe/LxssUserSession.cpp index ef4cfd7044..db207b1411 100644 --- a/src/windows/service/exe/LxssUserSession.cpp +++ b/src/windows/service/exe/LxssUserSession.cpp @@ -967,8 +967,6 @@ HRESULT LxssUserSessionImpl::MoveDistribution(_In_ LPCGUID DistroGuid, _In_ LPCW ::SetSecurityInfo(vhdHandle.get(), SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, originalOwner, nullptr, nullptr, nullptr)); }; - setVhdOwner(newVhdPath); - auto revert = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&]() { THROW_IF_WIN32_BOOL_FALSE(MoveFileEx( newVhdPath.c_str(), distro.VhdFilePath.c_str(), MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)); @@ -980,6 +978,8 @@ HRESULT LxssUserSessionImpl::MoveDistribution(_In_ LPCGUID DistroGuid, _In_ LPCW registration.Write(Property::BasePath, distro.BasePath.c_str()); }); + setVhdOwner(newVhdPath); + // Update the registry location registration.Write(Property::BasePath, Location); registration.Write(Property::VhdFileName, newVhdPath.filename().c_str()); From 67f1523232a472e6b9120b69a718ccc25d2d8240 Mon Sep 17 00:00:00 2001 From: Feng Wang Date: Thu, 16 Jul 2026 18:26:06 +0800 Subject: [PATCH 02/10] Fix execution context order --- src/windows/service/exe/LxssUserSession.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/windows/service/exe/LxssUserSession.cpp b/src/windows/service/exe/LxssUserSession.cpp index db207b1411..dc9286fadb 100644 --- a/src/windows/service/exe/LxssUserSession.cpp +++ b/src/windows/service/exe/LxssUserSession.cpp @@ -891,11 +891,10 @@ HRESULT LxssUserSessionImpl::MountDisk( _Out_ int* Step, _Out_ LPWSTR* MountName) { - ExecutionContext context(Context::MountDisk); - std::lock_guard lock(m_instanceLock); return wil::ResultFromException([&]() { _CreateVm(); + ExecutionContext context(Context::MountDisk); const auto MountDiskType = WI_IsFlagSet(Flags, LXSS_ATTACH_MOUNT_FLAGS_VHD) ? WslCoreVm::DiskType::VHD : WslCoreVm::DiskType::PassThrough; const auto MountResult = m_utilityVm->MountDisk(Disk, MountDiskType, PartitionIndex, Name, Type, Options); const auto MountNameWide = wsl::shared::string::MultiByteToWide(MountResult.MountPointName); From 31225e21e94a6dedde7bb67de5122808cd05ac89 Mon Sep 17 00:00:00 2001 From: Feng Wang Date: Thu, 16 Jul 2026 18:26:25 +0800 Subject: [PATCH 03/10] Reject more invalid mount names --- src/windows/service/exe/WslCoreVm.cpp | 5 +++-- test/windows/MountTests.cpp | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/windows/service/exe/WslCoreVm.cpp b/src/windows/service/exe/WslCoreVm.cpp index 03ffba1983..14a4c90de8 100644 --- a/src/windows/service/exe/WslCoreVm.cpp +++ b/src/windows/service/exe/WslCoreVm.cpp @@ -2752,8 +2752,9 @@ std::string WslCoreVm::s_GetMountTargetName(_In_ PCWSTR Disk, _In_opt_ PCWSTR Na if (ARGUMENT_PRESENT(Name)) { auto mountName = wsl::shared::string::WideToMultiByte(Name); - // Throw if the name contains '/' since it is a linux path separator - THROW_HR_IF(WSL_E_VM_MODE_INVALID_MOUNT_NAME, mountName.find('/') != std::string::npos); + THROW_HR_IF( + WSL_E_VM_MODE_INVALID_MOUNT_NAME, + mountName.empty() || mountName == "." || mountName == ".." || mountName.find('/') != std::string::npos); return mountName; } diff --git a/test/windows/MountTests.cpp b/test/windows/MountTests.cpp index fbf5676648..8fbceeb3aa 100644 --- a/test/windows/MountTests.cpp +++ b/test/windows/MountTests.cpp @@ -341,6 +341,21 @@ class MountTests WaitForDiskReady(); } + WSL2_TEST_METHOD(SpecifyInvalidMountName) + { + SKIP_UNSUPPORTED_ARM64_MOUNT_TEST(); + + for (const auto* name : {L"\"\"", L".", L"..", L"foo/bar"}) + { + const auto mountCommand = std::format(L"--mount {} --vhd --name {} --partition 1", VhdDevice, name); + VERIFY_ARE_NOT_EQUAL(LxsstuLaunchWsl(mountCommand), (DWORD)0, name); + } + + const auto disk = GetBlockDeviceInWsl(); + VERIFY_IS_TRUE(IsBlockDevicePresent(disk)); + VERIFY_IS_FALSE(GetBlockDeviceMount(disk + L"1").has_value()); + } + // Test ensuring that name collision detection works in --mount --name WSL2_TEST_METHOD(SpecifyMountNameCollision) { From 56f85fb25b841bbe44937f028ce3bdc36766e091 Mon Sep 17 00:00:00 2001 From: Feng Wang Date: Fri, 17 Jul 2026 14:33:04 +0800 Subject: [PATCH 04/10] restore the disk to online if it was online --- src/windows/service/exe/WslCoreVm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/windows/service/exe/WslCoreVm.cpp b/src/windows/service/exe/WslCoreVm.cpp index 14a4c90de8..8c3070d1a1 100644 --- a/src/windows/service/exe/WslCoreVm.cpp +++ b/src/windows/service/exe/WslCoreVm.cpp @@ -1000,7 +1000,7 @@ ULONG WslCoreVm::AttachDiskLockHeld( if (WI_IsFlagSet(diskFlags, DiskStateFlags::Online)) { const auto diskHandle = wsl::windows::common::disk::OpenDevice(Disk, GENERIC_READ | GENERIC_WRITE, m_vmConfig.MountDeviceTimeout); - wsl::windows::common::disk::SetOnline(diskHandle.get(), false, m_vmConfig.MountDeviceTimeout); + wsl::windows::common::disk::SetOnline(diskHandle.get(), true, m_vmConfig.MountDeviceTimeout); } }); From aedc8e0506d94a14653f2693ac68162de9237d26 Mon Sep 17 00:00:00 2001 From: Feng Wang Date: Fri, 17 Jul 2026 15:13:39 +0800 Subject: [PATCH 05/10] drain all pending pids on SIGCHLD --- src/linux/init/init.cpp | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/linux/init/init.cpp b/src/linux/init/init.cpp index 5bd4c793e4..035b0f7815 100644 --- a/src/linux/init/init.cpp +++ b/src/linux/init/init.cpp @@ -2572,23 +2572,33 @@ Return Value: continue; } - int Status{}; - auto Pid = waitpid(-1, &Status, WNOHANG); - if (Pid == 0) - { - continue; - } - else if (Pid > 0) + bool distroInitExited = false; + for (;;) { - if (Pid == distroInitPid.value()) + int Status{}; + auto Pid = waitpid(-1, &Status, WNOHANG); + if (Pid == 0) + { + break; + } + else if (Pid > 0) + { + distroInitExited |= (Pid == distroInitPid.value()); + } + else if (errno == ECHILD) { - LOG_ERROR("Init has exited. Terminating distribution"); break; } + else + { + FATAL_ERROR("waitpid failed {}", errno); + } } - else if (errno != ECHILD) + + if (distroInitExited) { - FATAL_ERROR("waitpid failed {}", errno); + LOG_ERROR("Init has exited. Terminating distribution"); + break; } } } From 15c9dc6e53577e9a2aca9093df96716407d32b70 Mon Sep 17 00:00:00 2001 From: Feng Wang Date: Fri, 17 Jul 2026 15:23:50 +0800 Subject: [PATCH 06/10] avoid race condition between submit and cancel --- src/windows/common/WslCoreMessageQueue.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/windows/common/WslCoreMessageQueue.h b/src/windows/common/WslCoreMessageQueue.h index d8f3b8d43d..3578361698 100644 --- a/src/windows/common/WslCoreMessageQueue.h +++ b/src/windows/common/WslCoreMessageQueue.h @@ -171,10 +171,11 @@ class WslCoreMessageQueue const auto queueLock = m_lock.lock_exclusive(); THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_CANCELLED), m_isCanceled); m_workItems.emplace_back(new_result); + + // always maintain a 1:1 ratio for calls to SubmitWorkWithResults() and ::SubmitThreadpoolWork + SubmitThreadpoolWork(m_tpHandle.get()); } - // always maintain a 1:1 ratio for calls to SubmitWorkWithResults() and ::SubmitThreadpoolWork - SubmitThreadpoolWork(m_tpHandle.get()); return new_result; } catch (...) From ecc3419ee87506a5120b827b5ed5e1e294baf84d Mon Sep 17 00:00:00 2001 From: Feng Wang Date: Fri, 17 Jul 2026 15:34:05 +0800 Subject: [PATCH 07/10] fix wrong size comparison --- src/linux/init/util.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/linux/init/util.cpp b/src/linux/init/util.cpp index 966d0f3d9c..9b9f94ef60 100644 --- a/src/linux/init/util.cpp +++ b/src/linux/init/util.cpp @@ -3494,7 +3494,7 @@ int ProcessCreateProcessMessage(wsl::shared::Transaction& Transaction, gsl::span { execResult = 0; } - else if (execResult == sizeof(execResult)) + else if (ReadResult == sizeof(execResult)) { // Otherwise, return the error code to the service execResult = abs(execResult); From 979e604777851c26f1d8f71f236bd39a2f18af6f Mon Sep 17 00:00:00 2001 From: Feng Wang Date: Fri, 17 Jul 2026 15:41:40 +0800 Subject: [PATCH 08/10] Fix potential counter overflow on valid traffic --- src/linux/init/DnsServer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/linux/init/DnsServer.h b/src/linux/init/DnsServer.h index 41cc2ccaad..d4729bfbb7 100644 --- a/src/linux/init/DnsServer.h +++ b/src/linux/init/DnsServer.h @@ -44,8 +44,8 @@ class DnsServer wil::unique_fd m_tcpConnection; // Offset in m_currentDnsRequest indicating how much of the current DNS request on - // the TCP connection has been read. Using 2 bytes to represent the offset as the request length is represented using 2 bytes. - uint16_t m_currentRequestOffset = 0; + // the TCP connection has been read. + size_t m_currentRequestOffset = 0; // Buffer containing the current DNS request received on the TCP connection. std::vector m_currentDnsRequest; From fead178ef3719938e8494640b109eaf7b8ad283f Mon Sep 17 00:00:00 2001 From: Feng Wang Date: Fri, 17 Jul 2026 16:21:35 +0800 Subject: [PATCH 09/10] resolve comments --- src/windows/common/WslCoreMessageQueue.h | 5 +++-- test/windows/MountTests.cpp | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/windows/common/WslCoreMessageQueue.h b/src/windows/common/WslCoreMessageQueue.h index 3578361698..72d6e64269 100644 --- a/src/windows/common/WslCoreMessageQueue.h +++ b/src/windows/common/WslCoreMessageQueue.h @@ -195,10 +195,11 @@ class WslCoreMessageQueue const auto queueLock = m_lock.lock_exclusive(); THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_CANCELLED), m_isCanceled); m_workItems.emplace_back(std::forward(functor)); + + // always maintain a 1:1 ratio for calls to SubmitWork() and ::SubmitThreadpoolWork + SubmitThreadpoolWork(m_tpHandle.get()); } - // always maintain a 1:1 ratio for calls to SubmitWork() and ::SubmitThreadpoolWork - SubmitThreadpoolWork(m_tpHandle.get()); return true; } catch (...) diff --git a/test/windows/MountTests.cpp b/test/windows/MountTests.cpp index 8fbceeb3aa..3c40454c5d 100644 --- a/test/windows/MountTests.cpp +++ b/test/windows/MountTests.cpp @@ -345,6 +345,8 @@ class MountTests { SKIP_UNSUPPORTED_ARM64_MOUNT_TEST(); + FormatDisk({L"ext4"}, true); + for (const auto* name : {L"\"\"", L".", L"..", L"foo/bar"}) { const auto mountCommand = std::format(L"--mount {} --vhd --name {} --partition 1", VhdDevice, name); From 7e4bef7b676051696c9ee0cdaf425d3ae17625d3 Mon Sep 17 00:00:00 2001 From: Feng Wang Date: Fri, 17 Jul 2026 16:32:07 +0800 Subject: [PATCH 10/10] update outdated comment --- src/windows/common/WslCoreMessageQueue.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/windows/common/WslCoreMessageQueue.h b/src/windows/common/WslCoreMessageQueue.h index 72d6e64269..11b75a5b6e 100644 --- a/src/windows/common/WslCoreMessageQueue.h +++ b/src/windows/common/WslCoreMessageQueue.h @@ -172,7 +172,7 @@ class WslCoreMessageQueue THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_CANCELLED), m_isCanceled); m_workItems.emplace_back(new_result); - // always maintain a 1:1 ratio for calls to SubmitWorkWithResults() and ::SubmitThreadpoolWork + // always maintain a 1:1 ratio for calls to submit_with_results() and ::SubmitThreadpoolWork SubmitThreadpoolWork(m_tpHandle.get()); } @@ -196,7 +196,7 @@ class WslCoreMessageQueue THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_CANCELLED), m_isCanceled); m_workItems.emplace_back(std::forward(functor)); - // always maintain a 1:1 ratio for calls to SubmitWork() and ::SubmitThreadpoolWork + // always maintain a 1:1 ratio for calls to submit() and ::SubmitThreadpoolWork SubmitThreadpoolWork(m_tpHandle.get()); }