271
// Create the VM in the SYSTEM service (privileged).
272
auto vm = Microsoft::WRL::Make<HcsVirtualMachine>(Settings);
273
274
- // Launch per-user COM server factory and add it to our job object for crash cleanup.
274
+ // Launch per-user COM server factory and add it to a fresh per-session job object for crash cleanup.
275
auto factory = wslutil::CreateComServerAsUser<IWSLCSessionFactory>(__uuidof(WSLCSessionFactory), userToken.get());
276
- AddSessionProcessToJobObject(factory.get());
276
+ wil::unique_handle sessionJob = CreateSessionProcessJob(factory.get());
277
278
const auto sessionSettings = CreateSessionSettings(sessionId, callerFileName.c_str(), Settings, resolvedDisplayName.c_str());
279
wil::com_ptr<IWSLCSession> session;
282
283
// Track the session via its service ref, along with metadata and security info.
284
m_sessions.push_back(SessionEntry{
285
- std::move(serviceRef), sessionId, creatorPid, resolvedDisplayName, std::move(tokenInfo), notifier, false, sharedToken, std::move(storedSid)});
285
+ std::move(serviceRef), sessionId, creatorPid, resolvedDisplayName, std::move(tokenInfo), notifier, false, sharedToken, std::move(storedSid), std::move(sessionJob)});
286
287
// For persistent sessions, also hold a strong reference to keep them alive.
288
const bool persistent = WI_IsFlagSet(Flags, WSLCSessionFlagsPersistent);
445
return sessionSettings;
446
}
447
448
-void WSLCSessionManagerImpl::AddSessionProcessToJobObject(_In_ IWSLCSessionFactory* Factory)
448
+wil::unique_handle WSLCSessionManagerImpl::CreateSessionProcessJob(_In_ IWSLCSessionFactory* Factory)
449
{
450
- EnsureJobObjectCreated();
450
+ // Use a fresh job per session; reusing one fails intermittently with
451
+ // ERROR_ACCESS_DENIED once it's assigned to a process the system put in another job.
452
+ wil::unique_handle jobObject = wsl::windows::common::helpers::CreateKillOnCloseJob();
453
454
wil::unique_handle process;
455
THROW_IF_FAILED(Factory->GetProcessHandle(process.put()));
456
455
- THROW_IF_WIN32_BOOL_FALSE(AssignProcessToJobObject(m_sessionJobObject.get(), process.get()));
456
-}
457
+ THROW_IF_WIN32_BOOL_FALSE(AssignProcessToJobObject(jobObject.get(), process.get()));
458
458
-void WSLCSessionManagerImpl::EnsureJobObjectCreated()
459
-{
460
- // Create a job object that will automatically terminate all child processes
461
- // when the job handle is closed (i.e., when wslservice exits or crashes).
462
- std::call_once(m_jobObjectInitFlag, [this] {
463
- m_sessionJobObject = wsl::windows::common::helpers::CreateKillOnCloseJob();
464
- WSL_LOG("SessionManagerJobObjectCreated", TraceLoggingLevel(WINEVENT_LEVEL_INFO));
465
- });
459
+ return jobObject;
460
}
461
462
CallingProcessTokenInfo WSLCSessionManagerImpl::GetCallingProcessTokenInfo()