Skip to content

Fix crash in filesFromStatus: when piece bitfield is empty#2

Open
mrowlinson wants to merge 1 commit into
XITRIX:mainfrom
mrowlinson:fix/filesFromStatus-empty-bitfield
Open

Fix crash in filesFromStatus: when piece bitfield is empty#2
mrowlinson wants to merge 1 commit into
XITRIX:mainfrom
mrowlinson:fix/filesFromStatus-empty-bitfield

Conversation

@mrowlinson

Copy link
Copy Markdown

Summary

filesFromStatus: calls stat.pieces.get_bit(index) for every piece of every file. When a torrent has just been added and the piece check has not yet populated stat.pieces, the bitfield's backing storage is empty and get_bit dereferences null internal storage, crashing with EXC_BAD_ACCESS / KERN_INVALID_ADDRESS at 0x4.

This patch bounds-checks each piece index against stat.pieces.size() and falls back to @NO for indices the bitfield does not yet cover. Once the piece check populates the bitfield the snapshot is refreshed with the real bits.

Reproduction

LibTorrent-Swift 2.0.11 (commit 70ca1a7) inside a host iTorrent build, on iOS 26.4.2, iPhone 17 Pro Max:

  1. Build & run the host app on a device.
  2. Add any new torrent (file or magnet).
  3. TorrentHandle.prepareToAdd runs updateSnapshot synchronously, which calls filesFromStatus: on a status snapshot whose pieces bitfield is still empty → crash.

Top of the faulting stack from the .ips report:

libtorrent::bitfield::get_bit(int) const
libtorrent::typed_bitfield<piece_index_tag>::get_bit(...)
-[TorrentHandle filesFromStatus:]                                     ← TorrentHandle.mm:398
-[TorrentHandle updateSnapshot]                                       ← TorrentHandle.mm:506
closure #1 in closure #1 in TorrentHandle.prepareToAdd(into:)
exception:
  type: EXC_BAD_ACCESS
  signal: SIGSEGV
  subtype: KERN_INVALID_ADDRESS at 0x0000000000000004

Test plan

  • Build passes (xcodebuild -workspace ... -scheme iTorrent -destination 'generic/platform=iOS' build)
  • App launches on device after the patch
  • Adding a new torrent no longer crashes; piece-status array is populated correctly once the piece check completes

When a torrent has just been added and the piece check has not yet
populated stat.pieces, the bitfield's backing storage can be empty.
Calling stat.pieces.get_bit(index) in that state dereferences null
internal storage, crashing with EXC_BAD_ACCESS at a small address
(0x4 in the trace below).

Bounds-check each piece index against stat.pieces.size() and fall back
to @no when the bitfield does not yet cover the index. Once the piece
check completes the snapshot will be refreshed with the real bits.

Reproduces in 2.0.11 by adding any new torrent: TorrentHandle.prepareToAdd
triggers updateSnapshot synchronously, which calls filesFromStatus on a
status snapshot whose pieces bitfield has not been initialised yet.
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.

1 participant