@samitouri / QOSAMI-WSL / commits / 976fb491

Revert "Mount plugin folders on behalf of the user owning the wsl session" (#41331) (#41515)

Temporarily reverting the identity-based plugin folder mount change (both the WslCoreVm.cpp behavior change and the accompanying MountFolderAccess test coverage) introduced in #41331. This reverts commit 78b9cf201df66ea470dc6de096ef6722905ba785. Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Ben Hillis committed Sep 3, 2026 at 16:27 UTC 976fb491a16d6da7d5e6321612470e9df7d9395e
4 files changed +4 -79
src/windows/service/exe/WslCoreVm.cpp
+1 -2
@@ -2101,8 +2101,7 @@ void WslCoreVm::MountRootNamespaceFolder(_In_ LPCWSTR HostPath, _In_ LPCWSTR Gue
2101 auto lock = m_lock.lock_exclusive();
2102
2103 const auto flags = (ReadOnly ? hcs::Plan9ShareFlags::ReadOnly : hcs::Plan9ShareFlags::None) | hcs::Plan9ShareFlags::AllowOptions;
2104 - wsl::windows::common::hcs::AddPlan9Share(
2105 - m_system.get(), Name, Name, HostPath, LX_INIT_UTILITY_VM_PLAN9_PORT, flags, m_userToken.get());
2104 + wsl::windows::common::hcs::AddPlan9Share(m_system.get(), Name, Name, HostPath, LX_INIT_UTILITY_VM_PLAN9_PORT, flags);
2105
2106 wsl::shared::MessageWriter<LX_MINI_INIT_MOUNT_FOLDER_MESSAGE> message(LxMiniInitMountFolder);
2107 message.WriteString(message->PathIndex, GuestPath);
test/windows/PluginTests.cpp
+1 -58
@@ -89,7 +89,7 @@ class PluginTests
89 return true;
90 }
91
92 - void ConfigurePlugin(PluginTestType testCase, LPCWSTR mountFolder = L"") const
92 + void ConfigurePlugin(PluginTestType testCase) const
93 {
94 StopWslService();
95 if (!DeleteFile(logFile.c_str()))
@@ -100,7 +100,6 @@ class PluginTests
100 const auto testKey = OpenTestRegistryKey(KEY_SET_VALUE);
101 WriteDword(testKey.get(), nullptr, c_testType, static_cast<DWORD>(testCase));
102 WriteString(testKey.get(), nullptr, c_logFile, logFile.c_str());
103 - WriteString(testKey.get(), nullptr, c_mountFolder, mountFolder);
103
104 const auto lxssKey =
105 CreateKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Lxss\\Plugins", KEY_SET_VALUE, nullptr, 0);
@@ -173,62 +172,6 @@ class PluginTests
172 ValidateLogFile(ExpectedOutput);
173 }
174
176 - WSL2_TEST_METHOD(MountFolderAccess)
177 - {
178 - const auto testFolder = std::filesystem::current_path() / "deny-write";
179 - VERIFY_IS_TRUE(std::filesystem::create_directory(testFolder));
180 -
181 - auto cleanup = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&]() { std::filesystem::remove_all(testFolder); });
182 -
183 - const auto user = wil::get_token_information<TOKEN_USER>();
184 - EXPLICIT_ACCESSW access{};
185 - access.grfAccessPermissions = FILE_ADD_FILE;
186 - access.grfAccessMode = DENY_ACCESS;
187 - access.grfInheritance = NO_INHERITANCE;
188 - access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
189 - access.Trustee.ptstrName = static_cast<LPWSTR>(user->User.Sid);
190 -
191 - PACL acl = nullptr;
192 - wil::unique_hlocal descriptor;
193 - THROW_IF_WIN32_ERROR(GetNamedSecurityInfoW(
194 - testFolder.c_str(), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, nullptr, nullptr, &acl, nullptr, &descriptor));
195 -
196 - wsl::windows::common::security::unique_acl newAcl;
197 - THROW_IF_WIN32_ERROR(SetEntriesInAclW(1, &access, acl, &newAcl));
198 - THROW_IF_WIN32_ERROR(SetNamedSecurityInfoW(
199 - const_cast<LPWSTR>(testFolder.c_str()), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, nullptr, nullptr, newAcl.get(), nullptr));
200 -
201 - const auto testFile = testFolder / L"plugin-test.txt";
202 - wil::unique_hfile deniedFile{CreateFileW(testFile.c_str(), GENERIC_WRITE, 0, nullptr, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, nullptr)};
203 - VERIFY_IS_TRUE(!deniedFile);
204 - VERIFY_ARE_EQUAL(GetLastError(), ERROR_ACCESS_DENIED);
205 -
206 - auto resetAcl = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&]() {
207 - wsl::windows::common::security::unique_acl restoredAcl;
208 - access.grfAccessPermissions = 0;
209 - access.grfAccessMode = REVOKE_ACCESS;
210 -
211 - THROW_IF_WIN32_ERROR(SetEntriesInAclW(1, &access, acl, &restoredAcl));
212 -
213 - THROW_IF_WIN32_ERROR(SetNamedSecurityInfoW(
214 - const_cast<LPWSTR>(testFolder.c_str()), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, nullptr, nullptr, restoredAcl.get(), nullptr));
215 - });
216 -
217 - ConfigurePlugin(PluginTestType::MountFolderAccess, testFolder.c_str());
218 -
219 - constexpr auto ExpectedOutput =
220 - LR"(Plugin loaded. TestMode=25
221 - VM created (settings->CustomConfigurationFlags=0)
222 - /bin/sh: line 1: /test-plugin-access/plugin-test.txt: Permission denied
223 - Distribution started, name=test_distro, package=, PidNs=*, InitPid=*, Flavor=debian, Version=13
224 - Distribution Stopping, name=test_distro, package=, PidNs=*, Flavor=debian, Version=13
225 - VM Stopping)";
226 -
227 - StartWsl(0);
228 - VERIFY_IS_FALSE(std::filesystem::exists(testFile));
229 - ValidateLogFile(ExpectedOutput);
230 - }
231 -
175 WSL2_TEST_METHOD(CustomKernelOverriddenByPolicy)
176 {
177 RegistryKeyChange policy(
test/windows/PluginTests.h
+1 -3
@@ -44,13 +44,11 @@ enum class PluginTestType
44 WslcImagePull,
45 WslcVmRestart,
46 WslcVmStopCommitted,
47 - WslcVmNeverStarted,
48 - MountFolderAccess
47 + WslcVmNeverStarted
48 };
49
50 constexpr auto c_testType = L"TestType";
51 constexpr auto c_logFile = L"LogFile";
53 -constexpr auto c_mountFolder = L"MountFolder";
52
53 inline wil::unique_hkey OpenTestRegistryKey(REGSAM AccessMask)
54 {
test/windows/testplugin/Plugin.cpp
+1 -16
@@ -123,21 +123,6 @@ HRESULT OnVmStarted(const WSLSessionInformation* Session, const WSLVmCreationSet
123 return E_ABORT;
124 }
125 }
126 - else if (g_testType == PluginTestType::MountFolderAccess)
127 - {
128 - const auto key = OpenTestRegistryKey(KEY_READ);
129 - const auto mountSource = ReadString(key.get(), nullptr, c_mountFolder);
130 -
131 - RETURN_IF_FAILED(
132 - g_api->MountFolder(Session->SessionId, mountSource.c_str(), L"/test-plugin-access", false, L"test-plugin-access"));
133 -
134 - std::vector<const char*> arguments = {"/bin/sh", "-c", "{ echo test > /test-plugin-access/plugin-test.txt; } 2>&1", nullptr};
135 - wil::unique_socket socket;
136 - RETURN_IF_FAILED(g_api->ExecuteBinary(Session->SessionId, arguments[0], arguments.data(), &socket));
137 -
138 - const auto output = ReadFromSocket(socket.get());
139 - g_logfile.write(output.data(), output.size());
140 - }
126 else if (g_testType == PluginTestType::ApiErrors)
127 {
128 auto result = g_api->MountFolder(Session->SessionId, L"C:\\DoesNotExit", L"/dummy", true, L"test-plugin-mount");
@@ -802,7 +787,7 @@ EXTERN_C __declspec(dllexport) HRESULT WSLPLUGINAPI_ENTRYPOINTV1(const WSLPlugin
787 THROW_HR_IF(E_UNEXPECTED, !g_logfile);
788
789 g_testType = static_cast<PluginTestType>(ReadDword(key.get(), nullptr, c_testType, static_cast<DWORD>(PluginTestType::Invalid)));
805 - THROW_HR_IF(E_INVALIDARG, static_cast<DWORD>(g_testType) <= 0 || static_cast<DWORD>(g_testType) > static_cast<DWORD>(PluginTestType::MountFolderAccess));
790 + THROW_HR_IF(E_INVALIDARG, static_cast<DWORD>(g_testType) <= 0 || static_cast<DWORD>(g_testType) > static_cast<DWORD>(PluginTestType::WslcVmNeverStarted));
791
792 g_logfile << "Plugin loaded. TestMode=" << static_cast<DWORD>(g_testType) << std::endl;
793 g_api = Api;