Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/linux/init/GnsPortTracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ std::optional<GnsPortTracker::BindCall> GnsPortTracker::GetCallInfo(
uint64_t CallId, pid_t Pid, int Arch, int SysCallNumber, const gsl::span<unsigned long long>& Arguments)
{
auto ParseSocket = [&](int Socket, size_t AddressPtr, size_t AddressLength) -> std::optional<BindCall> {
if (AddressLength < sizeof(sockaddr))
if (AddressLength < sizeof(sockaddr) || AddressLength > sizeof(sockaddr_storage))
{
return {{{}, {}, CallId}}; // Invalid sockaddr. Let it go through.
}
Expand Down
4 changes: 3 additions & 1 deletion src/linux/init/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2170,7 +2170,9 @@ Return Value:

try
{
wil::unique_fd InitFd{open(Target, (O_CREAT | O_WRONLY | O_TRUNC), 0755)};
THROW_LAST_ERROR_IF(unlink(Target) < 0 && errno != ENOENT);

wil::unique_fd InitFd{open(Target, (O_CREAT | O_EXCL | O_WRONLY), 0755)};
THROW_LAST_ERROR_IF(!InitFd);

THROW_LAST_ERROR_IF(mount(LX_INIT_PATH, Target, nullptr, (MS_RDONLY | MS_BIND), nullptr) < 0);
Expand Down
24 changes: 13 additions & 11 deletions src/windows/common/WslClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,9 @@ int ExportDistribution(_In_ std::wstring_view commandLine)
ArgumentParser parser(std::wstring{commandLine}, WSL_BINARY_NAME);
std::filesystem::path filePath;
LPCWSTR name{};
int tarFormatSet = 0;

auto parseFormat = [&flags](LPCWSTR Value) {
auto parseFormat = [&flags, &tarFormatSet](LPCWSTR Value) {
if (Value == nullptr)
{
return -1;
Expand All @@ -242,7 +243,11 @@ int ExportDistribution(_In_ std::wstring_view commandLine)
{
WI_SetFlag(flags, LXSS_EXPORT_DISTRO_FLAGS_VHD);
}
else if (!wsl::shared::string::IsEqual(L"tar", Value))
else if (wsl::shared::string::IsEqual(L"tar", Value))
{
tarFormatSet = 1;
}
else
{
THROW_HR(E_INVALIDARG);
}
Expand All @@ -256,9 +261,8 @@ int ExportDistribution(_In_ std::wstring_view commandLine)
parser.AddArgument(parseFormat, WSL_EXPORT_ARG_FORMAT_OPTION);
parser.Parse();

THROW_HR_IF(
WSL_E_INVALID_USAGE,
filePath.empty() || (WI_IsFlagSet(flags, LXSS_EXPORT_DISTRO_FLAGS_GZIP) && WI_IsFlagSet(flags, LXSS_EXPORT_DISTRO_FLAGS_VHD)));
constexpr ULONG c_exportFormatFlags = LXSS_EXPORT_DISTRO_FLAGS_VHD | LXSS_EXPORT_DISTRO_FLAGS_GZIP | LXSS_EXPORT_DISTRO_FLAGS_XZIP;
THROW_HR_IF(WSL_E_INVALID_USAGE, filePath.empty() || std::popcount(flags & c_exportFormatFlags) + tarFormatSet > 1);

// Determine if the target is stdout, or an on-disk file.
wil::unique_hfile file;
Expand Down Expand Up @@ -926,12 +930,10 @@ int Manage(_In_ std::wstring_view commandLine)
else if (defaultUser)
{
auto wslExe = wil::GetModuleFileNameW<std::wstring>(wil::GetModuleInstanceHandle());

auto commandLine = std::format(
L"\"{}\" {} -u root /usr/bin/id -u -- '{}'",
wslExe,
wsl::shared::string::GuidToString<wchar_t>(distroGuid),
defaultUser.value());
const auto distroGuidString = wsl::shared::string::GuidToString<wchar_t>(distroGuid);
const std::array<std::wstring_view, 9> arguments{
wslExe, distroGuidString, WSL_USER_ARG, L"root", WSL_EXEC_ARG, L"/usr/bin/id", L"-u", L"--", defaultUser.value()};
const auto commandLine = wil::ArgvToCommandLine(arguments);

wsl::windows::common::SubProcess process{wslExe.c_str(), commandLine.c_str()};

Expand Down
1 change: 1 addition & 0 deletions src/windows/common/precomp.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ Module Name:
#include <format>
#include <cwctype>
#include <variant>
#include <bit>

// Socket APIs
#include <mswsock.h>
Expand Down
1 change: 1 addition & 0 deletions src/windows/service/exe/WslCoreGuestNetworkService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ void wsl::core::networking::GuestNetworkService::CreateGuestNetworkService(
TraceLoggingHResult(result, "result"),
TraceLoggingValue(error.is_valid() ? error.get() : L"null", "errorString"));
THROW_IF_FAILED_MSG(result, "%ls", error.get());
m_id = VmId;

m_guestNetworkServiceCallback = windows::common::hcs::RegisterGuestNetworkServiceCallback(m_service, Callback, CallbackContext);
SetGuestNetworkServiceState(hns::GuestNetworkServiceState::Bootstrapping);
Expand Down
35 changes: 30 additions & 5 deletions src/windows/service/exe/WslCoreNetworkEndpoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#pragma once
#include <memory>
#include <optional>
#include <utility>
#include <hcs.hpp>

#include "WslCoreNetworkEndpointSettings.h"
Expand All @@ -16,15 +17,29 @@ struct NetworkEndpoint

~NetworkEndpoint() noexcept
{
if (Endpoint)
DeleteEndpoint();
}

NetworkEndpoint(NetworkEndpoint&&) = default;
NetworkEndpoint& operator=(NetworkEndpoint&& source) noexcept
{
if (this != &source)
{
wil::unique_cotaskmem_string error;
LOG_IF_FAILED_MSG(::HcnDeleteEndpoint(EndpointId, &error), "error message: %ls", error.get());
DeleteEndpoint();
StateTracking.reset();

Network = std::move(source.Network);
NetworkId = source.NetworkId;
EndpointId = source.EndpointId;
InterfaceGuid = source.InterfaceGuid;
InterfaceLuid = source.InterfaceLuid;
Endpoint = std::move(source.Endpoint);
StateTracking = std::move(source.StateTracking);
}

return *this;
}

NetworkEndpoint(NetworkEndpoint&&) = default;
NetworkEndpoint& operator=(NetworkEndpoint&& source) = default;
NetworkEndpoint(const NetworkEndpoint&) = delete;
NetworkEndpoint& operator=(const NetworkEndpoint&) = delete;

Expand All @@ -36,6 +51,16 @@ struct NetworkEndpoint
windows::common::hcs::unique_hcn_endpoint Endpoint{};
std::optional<IpStateTracking> StateTracking;

void DeleteEndpoint() noexcept
{
if (Endpoint)
{
wil::unique_cotaskmem_string error;
LOG_IF_FAILED_MSG(::HcnDeleteEndpoint(EndpointId, &error), "error message: %ls", error.get());
Comment thread
chemwolf6922 marked this conversation as resolved.
Endpoint.reset();
}
}

void TraceLoggingRundown() const
{
if (Network)
Expand Down
19 changes: 19 additions & 0 deletions test/windows/UnitTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,9 @@ class UnitTests
VERIFY_ARE_EQUAL(out, L"This operation is only supported by WSL2.\r\nError code: Wsl/Service/WSL_E_WSL2_NEEDED\r\n");
VERIFY_ARE_EQUAL(err, L"");
}

VerifyInvalidUsage(std::format(L"--export {} {} --format tar.gz --format tar.xz", LXSS_DISTRO_NAME_TEST_L, tarPath));
VerifyInvalidUsage(std::format(L"--export {} {} --format tar.xz --vhd", LXSS_DISTRO_NAME_TEST_L, tarPath));
}

WSL2_TEST_METHOD(SystemdSafeMode)
Expand Down Expand Up @@ -4365,6 +4368,22 @@ localhostForwarding=true

VERIFY_ARE_EQUAL(
out, L"There is no distribution with the supplied name.\r\nError code: Wsl/Service/WSL_E_DISTRO_NOT_FOUND\r\n");

constexpr auto injectionMarker = L"/tmp/wsl-manage-default-user-injection";
LxsstuLaunchWsl(std::format(L"-u root -e /usr/bin/rm -f {}", injectionMarker));
auto cleanupInjectionMarker = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [injectionMarker]() {
LxsstuLaunchWsl(std::format(L"-u root -e /usr/bin/rm -f {}", injectionMarker));
});

const auto injectionUsername = std::format(L"' || touch {} || '", injectionMarker);
const std::array<std::wstring_view, 4> injectionArguments{
WSL_MANAGE_ARG, LXSS_DISTRO_NAME_TEST_L, WSL_MANAGE_ARG_SET_DEFAULT_USER_OPTION_LONG, injectionUsername};
const auto injectionCommand = wil::ArgvToCommandLine(injectionArguments, wil::ArgvToCommandLineFlags::FirstArgumentIsNotPath);
auto injectionCommandLine = LxssGenerateWslCommandLine(injectionCommand.c_str());
const auto injectionExitCode = LxsstuRunCommand(injectionCommandLine.data());

VERIFY_ARE_EQUAL(LxsstuLaunchWsl(std::format(L"-u root -e /usr/bin/test ! -e {}", injectionMarker)), 0L);
VERIFY_ARE_EQUAL(injectionExitCode, 1L);
}

TEST_METHOD(PostDistroRegistrationSettingsOOBE)
Expand Down