Skip to content

Commit 454eae2

Browse files
Ben HillisCopilot
andcommitted
Preserve original VHD owner instead of using GetUserSid()
Instead of unconditionally setting the VHD owner to the caller's SID after a cross-volume move, read the original owner before the move and restore it afterward. This avoids changing ownership to someone who didn't originally own the file. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent fb32947 commit 454eae2

1 file changed

Lines changed: 12 additions & 5 deletions

File tree

src/windows/service/exe/LxssUserSession.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -939,21 +939,28 @@ HRESULT LxssUserSessionImpl::MoveDistribution(_In_ LPCGUID DistroGuid, _In_ LPCW
939939
THROW_WIN32(error.value());
940940
}
941941

942+
// Read the original VHD owner before the move so we can restore it after.
943+
// Cross-volume MoveFileEx may set the owner to BUILTIN\Administrators for
944+
// elevated callers, which breaks HcsGrantVmAccess (needs WRITE_DAC via
945+
// ownership) from non-elevated contexts.
946+
PSID originalOwner = nullptr;
947+
wil::unique_hlocal originalDescriptor;
948+
THROW_IF_WIN32_ERROR(GetNamedSecurityInfoW(
949+
distro.VhdFilePath.c_str(), SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, &originalOwner, nullptr, nullptr, nullptr, &originalDescriptor));
950+
942951
// Move the VHD to the new location.
943952
THROW_IF_WIN32_BOOL_FALSE(MoveFileEx(distro.VhdFilePath.c_str(), newVhdPath.c_str(), MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH));
944953

945-
// Set the VHD owner to the user's SID. Cross-volume MoveFileEx sets the
946-
// owner to BUILTIN\Administrators for elevated callers, which breaks
947-
// HcsGrantVmAccess (needs WRITE_DAC via ownership) from non-elevated contexts.
948-
auto setVhdOwner = [this](const std::filesystem::path& vhdPath) {
954+
// Restore the original VHD owner on the moved file.
955+
auto setVhdOwner = [&originalOwner](const std::filesystem::path& vhdPath) {
949956
wil::unique_hfile vhdHandle(CreateFileW(
950957
vhdPath.c_str(), WRITE_OWNER, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT, nullptr));
951958
THROW_LAST_ERROR_IF(!vhdHandle);
952959

953960
auto runAsSelf = wil::run_as_self();
954961
auto privileges = wsl::windows::common::security::AcquirePrivilege(SE_RESTORE_NAME);
955962
THROW_IF_WIN32_ERROR(
956-
::SetSecurityInfo(vhdHandle.get(), SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, GetUserSid(), nullptr, nullptr, nullptr));
963+
::SetSecurityInfo(vhdHandle.get(), SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, originalOwner, nullptr, nullptr, nullptr));
957964
};
958965

959966
setVhdOwner(newVhdPath);

0 commit comments

Comments
 (0)