Fix use-after-free in WSLCContainerImpl exec-process teardown#40822
Conversation
There was a problem hiding this comment.
Pull request overview
This PR addresses a use-after-free risk during container exec-process teardown by changing WSLCContainerImpl’s tracking of exec process controls from raw pointers to std::weak_ptr, and pinning controls with lock() before invoking teardown callbacks.
Changes:
- Replace
m_processesstorage fromstd::vector<DockerExecProcessControl*>tostd::vector<std::weak_ptr<DockerExecProcessControl>>. - Update exec creation to use
std::make_shared<DockerExecProcessControl>()and store weak references inm_processes. - Remove
WSLCContainerImpl::OnProcessReleased()and update teardown paths (ReleaseProcesses(), container destructor) to snapshot the weak list and safely notify live controls viaweak_ptr::lock().
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
src/windows/wslcsession/WSLCProcessControl.cpp |
Removes destructor callback into the container, relying on weak tracking to avoid UAF during teardown. |
src/windows/wslcsession/WSLCContainer.h |
Updates m_processes to store std::weak_ptr<DockerExecProcessControl> instead of raw pointers. |
src/windows/wslcsession/WSLCContainer.cpp |
Switches exec control creation to shared_ptr, stores weak refs, and pins controls with lock() during teardown notifications. |
OneBlue
left a comment
There was a problem hiding this comment.
LGTM ! It's wild that we never hit this during testing
| { | ||
| std::lock_guard processesLock{m_processesLock}; | ||
| // Snapshot under the lock, then notify outside it, pinning each control via lock() first | ||
| // (avoids the use after free, and avoids calling back under m_processesLock). |
There was a problem hiding this comment.
nit: I'd recommend removing the avoids the use after free since once merged, that comment will refer to an issue that won't exist anymore
| @@ -118,11 +118,7 @@ DockerExecProcessControl::DockerExecProcessControl( | |||
|
|
|||
| DockerExecProcessControl::~DockerExecProcessControl() | |||
There was a problem hiding this comment.
nit: This destructor can be removed since it's not doing anything
Summary of the Pull Request
Change m_processes to use weak pointers instead of raw pointers. Use lock() to pin on use.
PR Checklist
Detailed Description of the Pull Request / Additional comments
Validation Steps Performed
Existing tests