Skip to content

[5.5] [AST] Treat actors inheriting from NSObject as SwiftNativeNSObjects. #38804

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

Conversation

varungandhi-apple
Copy link
Contributor

@varungandhi-apple varungandhi-apple commented Aug 8, 2021

Previously, omitting @objc meant that ObjC-refcounting was used (even if : NSObject
was present), meaning that the multi-step deinitialization of different zombie states was
bypassed, leading to eager deallocation on the last release and user-after-free.

Fixes rdar://80863853.

(cherry picked from commit 4311a03)

Previously, there was a divergence in behavior between marking an actor as:
- objc: This would lead to usage of Swift reference counting.
- subclass of NSObject but not objc: This would lead to usage of ObjC
  reference counting.

By itself, this might seem OK, after all, the two reference counting
schemes are compatible (you can pass things from one language to another).

However, there is a difference here because actors have a multi-step
deinitialization process due to the way the reference accounting works
with tasks. When the last reference is released, the destroy() method is
called which only puts the actor into a Zombie_Latching state and deallocation
happens later on.

In contrast, when the ObjC runtime releases the last reference, it
immediately deallocates the actor, without calling the destroy() method
or having any awareness about actors.

This mismatch leads to a use-after-free in the Swift runtime; normally,
the actor would be in the Zombie_Latching state and when the final running
task finishes, it would end up deallocating the actor. This expectation
is not met when the memory is freed by the ObjC runtime, hence the UAF.

Normally, I would find it a bit odd to see a commit come with acknowledgements
but in this case I think maybe it's okay, given that this took me 2+ weeks to
investigate and fix. Thanks to:
- Dani C. in helping reproduce the issue with a large and small test case.
- John for answering questions about the actor and job lifecycle.
- Mike Ash for providing generous help with debugging.

Fixes rdar://80863853.

(cherry picked from commit 4311a03)
@varungandhi-apple varungandhi-apple requested a review from a team as a code owner August 8, 2021 07:56
@varungandhi-apple
Copy link
Contributor Author

@swift-ci test

@varungandhi-apple varungandhi-apple changed the title [AST] Treat actors inheriting from NSObject as SwiftNativeNSObjects. [5.5] [AST] Treat actors inheriting from NSObject as SwiftNativeNSObjects. Aug 8, 2021
@varungandhi-apple
Copy link
Contributor Author

Cherry-picked from #38803

@DougGregor DougGregor merged commit 97176fc into swiftlang:release/5.5 Aug 10, 2021
@varungandhi-apple varungandhi-apple deleted the vg-5.5-objc-actors-took-2-weeks-of-my-life branch August 10, 2021 18:23
@AnthonyLatsis AnthonyLatsis added 🍒 release cherry pick Flag: Release branch cherry picks swift 5.5 labels Jan 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🍒 release cherry pick Flag: Release branch cherry picks swift 5.5
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants