@samitouri / QOSAMI-WSL / commits / aef8dc3e

Preserve token owner during distribution move rollback (#41355)

* Preserve token owner during move rollback Save the duplicated caller token's original default owner before normalizing it for a distribution move. Restore that owner before a rollback so cross-volume rollback copies retain the caller token's prior ownership behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Restore VHD owner during move rollback Capture the source VHD owner before moving it and use that SID as the duplicated token's default owner for a cross-volume rollback. This leaves ownership unchanged when the operation fails. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Ben Hillis committed Aug 14, 2026 at 13:45 UTC aef8dc3e1ee57040249a0ec84e3fc47a84292d8a
1 file changed +11
src/windows/service/exe/LxssUserSession.cpp
+11
@@ -949,6 +949,14 @@ HRESULT LxssUserSessionImpl::MoveDistribution(_In_ LPCGUID DistroGuid, _In_ LPCW
949 // Cross-volume MoveFileEx creates a new file using the impersonation token's
950 // default owner. Normalize that owner to the caller's user SID so elevated moves
951 // do not produce a VHD owned by BUILTIN\Administrators.
952 + PSID originalVhdOwner = nullptr;
953 + wil::unique_hlocal originalSecurityDescriptor;
954 + {
955 + auto impersonate = wil::impersonate_token(userToken.get());
956 + THROW_IF_WIN32_ERROR(GetNamedSecurityInfoW(
957 + distro.VhdFilePath.c_str(), SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, &originalVhdOwner, nullptr, nullptr, nullptr, &originalSecurityDescriptor));
958 + }
959 +
960 auto tokenUser = wil::get_token_information<TOKEN_USER>(userToken.get());
961 TOKEN_OWNER tokenOwner{tokenUser->User.Sid};
962 THROW_IF_WIN32_BOOL_FALSE(SetTokenInformation(userToken.get(), TokenOwner, &tokenOwner, sizeof(tokenOwner)));
@@ -967,6 +975,9 @@ HRESULT LxssUserSessionImpl::MoveDistribution(_In_ LPCGUID DistroGuid, _In_ LPCW
975 }
976
977 auto revert = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&]() {
978 + TOKEN_OWNER originalOwner{originalVhdOwner};
979 + LOG_IF_WIN32_BOOL_FALSE(SetTokenInformation(userToken.get(), TokenOwner, &originalOwner, sizeof(originalOwner)));
980 +
981 auto impersonate = wil::impersonate_token(userToken.get());
982 if (!MoveFileExW(destPath.c_str(), distro.VhdFilePath.c_str(), MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH))
983 {