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: possible heap-use-after-free with magnet links #6815

Merged
merged 5 commits into from
May 24, 2024

Conversation

tearfur
Copy link
Member

@tearfur tearfur commented Apr 27, 2024

Fixes #6706.
Stack trace at #4178 (comment).

This PR backtracks some changes made in #6383:

  • Reverted a change that queues the tr_torrentVerify() call instead of executing it immediately after completing the metadata of a magnet link. This is the crux of the bug this PR fixes, more on that below.
  • Re-implemented tr_torrentMagnetDoIdleWork() that got removed.

#6383 changed tr_torrent::on_metainfo_completed() so that it queues tr_torrentVerify() to be executed in the session thread when it is free, instead of executing it immediately.

This was needed because tr_torrentVerify() will stop the torrent, thus freeing all tr_peerMsgs objects belonging to that torrent (i.e. disconnecting all peers), and this might trigger a chain reaction (detailed at #6383 (comment)) that leads to heap-use-after-free.

However, an unexpected consequence of this change is, there is a chance that tr_torrentVerify() will be executed after the original tr_torrent object for the magnet link is destructed, causing heap-use-after-free. This can happen if the magnet link got removed from Transmission or the session itself got shut down immediately after the metadata transfer completed.

A side effect of this PR is that we need to re-introduce the indirection step tr_torrentMagnetDoIdleWork(), otherwise there will be heap-use-after-free. I made the changes in #6383 because I didn't like how it worked, but for now I don't see any better solution other then reverting to the way it was.

@tearfur tearfur added the notes:none Should not be listed in release notes label Apr 27, 2024
@tearfur tearfur marked this pull request as draft April 27, 2024 15:26
@tearfur tearfur force-pushed the set-metadata-piece-test branch 2 times, most recently from e6e8c9e to 9076d50 Compare April 27, 2024 17:07
@tearfur tearfur marked this pull request as ready for review April 27, 2024 17:19
Copy link
Collaborator

@Coeur Coeur left a comment

Choose a reason for hiding this comment

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

Looks good. Thanks

@Coeur Coeur added this to the 4.1.0 milestone Apr 27, 2024
Copy link
Member

@ckerr ckerr left a comment

Choose a reason for hiding this comment

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

I like this change!

IMO we can do this without exposing a new public method in tr_torrent but 👍 with the approach of moving this to an idle func

libtransmission/peer-mgr.cc Outdated Show resolved Hide resolved
libtransmission/torrent-magnet.h Outdated Show resolved Hide resolved
@tearfur tearfur removed their assignment May 5, 2024
@Coeur Coeur requested a review from ckerr May 5, 2024 03:24
@ckerr ckerr merged commit 09b67c8 into transmission:main May 24, 2024
23 of 25 checks passed
@tearfur tearfur deleted the set-metadata-piece-test branch May 24, 2024 23:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
notes:none Should not be listed in release notes scope:core scope:test type:fix A bug fix
Development

Successfully merging this pull request may close these issues.

LT.TorrentMagnetTest.setMetadataPiece (SEGFAULT) on OpenBSD/amd64
3 participants