wslcsession: use DuplicateHandle idiom for self-process handle in GetProcessHandle#40748
Open
benhillis wants to merge 1 commit into
Open
wslcsession: use DuplicateHandle idiom for self-process handle in GetProcessHandle#40748benhillis wants to merge 1 commit into
benhillis wants to merge 1 commit into
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes intermittent E_ACCESSDENIED when WSLC exposes a handle to its own COM server process under COM impersonation by avoiding OpenProcess() (which performs an access check against the thread’s effective token) and instead duplicating the current-process pseudo-handle.
Changes:
- Replace
OpenProcess(PROCESS_SET_QUOTA | PROCESS_TERMINATE, ...)withwslutil::DuplicateHandle(GetCurrentProcess(), ...)in WSLC session and factoryGetProcessHandleimplementations. - Add an explicit
E_POINTERguard inWSLCSessionFactory::GetProcessHandle.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/windows/wslcsession/WSLCSessionFactory.cpp | Switch self-process handle creation to wslutil::DuplicateHandle to avoid impersonation-related access checks. |
| src/windows/wslcsession/WSLCSession.cpp | Switch self-process handle creation to wslutil::DuplicateHandle to avoid impersonation-related access checks. |
OneBlue
reviewed
Jun 9, 2026
OneBlue
left a comment
Collaborator
There was a problem hiding this comment.
FYI debugging showed that the error wasn't returned from OpenProcess(), but from AssignProcessToJobObject() in wslservice.exe, so I'm not sure that this will solve the issue
…ProcessHandle Replace OpenProcess(GetCurrentProcessId()) in IWSLCSessionFactory::GetProcessHandle and IWSLCSession::GetProcessHandle with a duplicate of the GetCurrentProcess() pseudo-handle via wslutil::DuplicateHandle. A process should not need an access check to obtain a handle to itself; duplicating the pseudo-handle is the canonical idiom and avoids OpenProcess's access check against the calling thread's (possibly impersonated) effective token. An explicit desired-access mask keeps the handle's rights identical (PROCESS_SET_QUOTA | PROCESS_TERMINATE), so the marshaled handle and downstream usage are unchanged. This is a cleanup/hardening change. It does not fix the 0x80070005 seen after hibernate/resume, which originates from AssignProcessToJobObject in wslservice.exe (WSLCSessionManager::AddSessionProcessToJobObject), not from GetProcessHandle. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
753c768 to
2e4172b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary of the Pull Request
Replace the self-
OpenProcess(GetCurrentProcessId())calls inIWSLCSessionFactory::GetProcessHandleandIWSLCSession::GetProcessHandlewith a duplicate of the current-process pseudo-handle via the existingwslutil::DuplicateHandlehelper.This is a cleanup/hardening change, not a behavioral one. A process should not need to
OpenProcessitself by PID to obtain a handle to itself — duplicating theGetCurrentProcess()pseudo-handle is the canonical idiom. The new call requests the same access rights (PROCESS_SET_QUOTA | PROCESS_TERMINATE), so the marshaled handle and all downstream usage are unchanged.Note
This does not fix the reported
0x80070005(E_ACCESSDENIED) seen after hibernate/resume. Debugging shows that failure originates fromAssignProcessToJobObjectinwslservice.exe(WSLCSessionManager::AddSessionProcessToJobObject, WSLCSessionManager.cpp:454), not fromGetProcessHandle. Both call sites surface the identical HRESULT, which is why it was initially misattributed. The job-assignment failure is being tracked separately.PR Checklist
Detailed Description of the Pull Request / Additional comments
GetProcessHandlepreviously did:wil::unique_handle process{OpenProcess(PROCESS_SET_QUOTA | PROCESS_TERMINATE, FALSE, GetCurrentProcessId())};OpenProcessperforms an access check against the calling thread's effective token. Using it to open your own process is unnecessary and fragile — there is no reason a process should need an access check to obtain a handle to itself.The replacement duplicates the current-process pseudo-handle:
DuplicateHandlefrom the pseudo-handle performs no object DACL access check (it only requiresPROCESS_DUP_HANDLEon theGetCurrentProcess()pseudo-handle, which is always granted), so it is the correct, robust idiom. Because an explicit desired-access mask is passed, the resulting handle carries exactlyPROCESS_SET_QUOTA | PROCESS_TERMINATE— identical to the previous handle.Validation Steps Performed
PROCESS_SET_QUOTA | PROCESS_TERMINATE), soAssignProcessToJobObjectconsumption is unchanged.