Skip to content
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

Fix a race condition bug involving timers and async tasks #6045

Merged

Conversation

buggmagnet
Copy link
Contributor

@buggmagnet buggmagnet commented Apr 2, 2024

This PR fixes a subtle bug where a DispatchSourceTimer is used alongside swift async code in an unsafe way.


This change is Reviewable

@buggmagnet buggmagnet added the iOS Issues related to iOS label Apr 2, 2024
@buggmagnet buggmagnet requested review from rablador and acb-mv April 2, 2024 08:13
@buggmagnet buggmagnet self-assigned this Apr 2, 2024
Copy link

linear bot commented Apr 2, 2024

Copy link
Collaborator

@pinkisemils pinkisemils left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 0 of 2 files reviewed, 1 unresolved discussion (waiting on @buggmagnet)


ios/PacketTunnelCore/Actor/Task+Duration.swift line 53 at r1 (raw file):

                var hasResumed = false
                timer.setEventHandler {
                    hasResumed = true

Is it never possible for this event handler to be invoked after the the continuation has already been cancelled?

Copy link
Contributor Author

@buggmagnet buggmagnet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 0 of 2 files reviewed, 1 unresolved discussion (waiting on @pinkisemils)


ios/PacketTunnelCore/Actor/Task+Duration.swift line 53 at r1 (raw file):

Previously, pinkisemils (Emīls Piņķis) wrote…

Is it never possible for this event handler to be invoked after the the continuation has already been cancelled?

The default repeating interval is .never so the timer won't fire its event handler more than once unless explicitly specified.

Copy link
Contributor Author

@buggmagnet buggmagnet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 0 of 2 files reviewed, 1 unresolved discussion (waiting on @pinkisemils)


ios/PacketTunnelCore/Actor/Task+Duration.swift line 53 at r1 (raw file):

Previously, buggmagnet wrote…

The default repeating interval is .never so the timer won't fire its event handler more than once unless explicitly specified.

If the continuation is cancelled before the timer fires, then it gets cancelled and its event handler shouldn't be scheduled anymore

Copy link
Contributor

@rablador rablador left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 2 of 2 files at r1, all commit messages.
Reviewable status: all files reviewed, 2 unresolved discussions (waiting on @buggmagnet and @pinkisemils)


ios/PacketTunnelCoreTests/TaskSleepTests.swift line 35 at r1 (raw file):

            var task = recoveryTask()
            try await Task.sleep(duration: .milliseconds(10))
            task.doAnythingToSilenceAWarning()

What does this do?

Copy link
Contributor Author

@buggmagnet buggmagnet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 1 of 2 files reviewed, 2 unresolved discussions (waiting on @pinkisemils and @rablador)


ios/PacketTunnelCoreTests/TaskSleepTests.swift line 35 at r1 (raw file):

Previously, rablador (Jon Petersson) wrote…

What does this do?

What it says on the tin !
Just kidding, I've added a comment and renamed the function to make it more explicit why we do this here.

Copy link
Collaborator

@pinkisemils pinkisemils left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 1 of 2 files at r1.
Reviewable status: 1 of 2 files reviewed, 2 unresolved discussions (waiting on @rablador)

Copy link
Collaborator

@pinkisemils pinkisemils left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 1 of 2 files at r1.
Reviewable status: 1 of 2 files reviewed, 2 unresolved discussions (waiting on @rablador)

Copy link
Collaborator

@pinkisemils pinkisemils left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 1 of 2 files reviewed, 2 unresolved discussions (waiting on @buggmagnet and @rablador)


ios/PacketTunnelCore/Actor/Task+Duration.swift line 53 at r1 (raw file):

Previously, buggmagnet wrote…

If the continuation is cancelled before the timer fires, then it gets cancelled and its event handler shouldn't be scheduled anymore

And the event handler and cancel handler are guaranteed to never be executed concurrently?

Copy link
Collaborator

@pinkisemils pinkisemils left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 1 of 2 files reviewed, 1 unresolved discussion (waiting on @rablador)


ios/PacketTunnelCore/Actor/Task+Duration.swift line 53 at r1 (raw file):

Previously, pinkisemils (Emīls Piņķis) wrote…

And the event handler and cancel handler are guaranteed to never be executed concurrently?

The docs answer my question.

Copy link
Collaborator

@pinkisemils pinkisemils left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 1 of 1 files at r2, all commit messages.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on @rablador)

Copy link
Contributor

@rablador rablador left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 1 of 1 files at r2, all commit messages.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved

Copy link
Contributor

@rablador rablador left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: :shipit: complete! all files reviewed, all discussions resolved

Copy link
Collaborator

@pinkisemils pinkisemils left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: :shipit: complete! all files reviewed, all discussions resolved

@pinkisemils pinkisemils force-pushed the fix-async-api-misuse-in-timer-source-usage-ios-582 branch from 40db7d8 to 8a71b5d Compare April 4, 2024 11:22
Copy link
Collaborator

@pinkisemils pinkisemils left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed all commit messages.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved

@pinkisemils pinkisemils merged commit be57953 into main Apr 4, 2024
7 checks passed
@pinkisemils pinkisemils deleted the fix-async-api-misuse-in-timer-source-usage-ios-582 branch April 4, 2024 11:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
iOS Issues related to iOS
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants