Skip to content

[5.6] Process: correct a subtle runLoopSource lifetime issue #3128

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 1, 2022

Conversation

compnerd
Copy link
Member

No description provided.

compnerd and others added 2 commits January 18, 2022 18:27
When a process is run with `run`, a monitoring thread is setup by means
of a socketpair.  This socket is used to create a runloop source, which
will monitor the process for termination.  `waitUntilExit` will monitor
the `isRunning` ivar which is set by the source to indicate the process
termination having been observed.  We however would previously mark the
process as terminated before invalidating the runloop source to prevent
any new callouts on the source. However, the operation is multithreaded
the operation is not guaranteed to be serialized and the runloop source
may be `nil`'ed prior or during the invalidation which also releases as
the refcount is now 0.  This would result in the `runloopSource` passed
to `CFRunLoopSourceInvalidate` being `nil` and breaking the contract of
the call or a UaF if the value is `nil`'ed during the execution.  These
states have both been observed in practice.  Reordering the `isRunning`
ivar assignment to occur after the invalidation ensures that the value
remains usable until we no longer reference it.
This fixes a data race between setting `process.isRunning = false`
and then calling `CFRunLoopSourceInvalidate(process.runLoopSource)`.
Process.waitUntilExit() may wake up and clear .runLoopSource which
results in a fairly common crash on Windows.

Put this logic in a common method to reduce drift between the
Darwin / Linux and Windows code paths.

Co-authored-by: Saleem Abdulrasool <[email protected]>
@compnerd
Copy link
Member Author

@swift-ci please test

@compnerd
Copy link
Member Author

Please test with following PRs:
swiftlang/swift-docc#72

@swift-ci please test Linux platform

@millenomi
Copy link
Contributor

cc @parkera OK for merging? This fixes a timing issue in detecting whether a Process-managed task has finished running.

@millenomi millenomi merged commit 0ee660a into swiftlang:release/5.6 Feb 1, 2022
@compnerd compnerd deleted the 5.6-sources branch February 1, 2022 20:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants