anacrolix / torrent

Full-featured BitTorrent client package and utilities
Mozilla Public License 2.0
5.41k stars 617 forks source link

panic: write overflows piece #788

Closed JaskaranSM closed 1 year ago

JaskaranSM commented 1 year ago

The client crashed with the logs as follows (pastelink):

panic: write overflows piece [recovered]
        panic: write overflows piece

goroutine 1687223 [running]:
github.com/anacrolix/missinggo/perf.ScopeTimerErr.func1()
        /home/runner/go/pkg/mod/github.com/anacrolix/missinggo/perf@v1.0.0/scope.go:23 +0xa5
panic({0x1772ac0, 0x1f212e0})
        /opt/hostedtoolcache/go/1.19.3/x64/src/runtime/panic.go:890 +0x262
github.com/anacrolix/torrent/storage.Piece.WriteAt({{0x1f38e00?, 0xc001f4a300?}, {0xc000c16600?, 0x504?}}, {0xc001e10000?, 0x38595f9053e4ec8a?, 0x195d2fd3?}, 0x504?)
        /home/runner/go/pkg/mod/github.com/anacrolix/torrent@v1.47.0/storage/wrappers.go:64 +0x275
github.com/anacrolix/torrent.(*Torrent).writeChunk(0xc0002b2a80, 0x504, 0x127b4a6?, {0xc001e10000, 0x4000, 0x4000})
        /home/runner/go/pkg/mod/github.com/anacrolix/torrent@v1.47.0/torrent.go:917 +0xeb
github.com/anacrolix/torrent.(*Peer).receiveChunk.func5(0xc0000d2d80, 0xc001147c50?, 0xc0004fa230)
        /home/runner/go/pkg/mod/github.com/anacrolix/torrent@v1.47.0/peerconn.go:1520 +0xee
github.com/anacrolix/torrent.(*Peer).receiveChunk(0xc00156cd00, 0xc0004fa230)
        /home/runner/go/pkg/mod/github.com/anacrolix/torrent@v1.47.0/peerconn.go:1521 +0x745
github.com/anacrolix/torrent.(*PeerConn).mainReadLoop(0xc00156cd00)
        /home/runner/go/pkg/mod/github.com/anacrolix/torrent@v1.47.0/peerconn.go:1255 +0x985
github.com/anacrolix/torrent.(*Client).runHandshookConn(0xc0000d2d80, 0xc00156cd00, 0xc0002b2a80)
        /home/runner/go/pkg/mod/github.com/anacrolix/torrent@v1.47.0/client.go:994 +0x4a5
github.com/anacrolix/torrent.(*Torrent).logRunHandshookConn(0xc0002b2a80, 0xc0002b2a80?, 0x0, {0x11?})
        /home/runner/go/pkg/mod/github.com/anacrolix/torrent@v1.47.0/torrent.go:1615 +0x52github.com/anacrolix/torrent.(*Torrent).runHandshookConnLoggingErr(...)
        /home/runner/go/pkg/mod/github.com/anacrolix/torrent@v1.47.0/torrent.go:1622
github.com/anacrolix/torrent.(*Client).outgoingConnection(0xc0000d2d80, 0x441725?, {0x1f2cbe0?, 0xc00008b820}, {0x1b5152f, 0x2}, 0x0)
        /home/runner/go/pkg/mod/github.com/anacrolix/torrent@v1.47.0/client.go:797 +0x3bb
created by github.com/anacrolix/torrent.(*Torrent).initiateConn
        /home/runner/go/pkg/mod/github.com/anacrolix/torrent@v1.47.0/torrent.go:2269 +0x25d

It was downloading three torrents, The progress status:

redacted - Downloading
[█▌           ] 12.05% , 7.4 GB of 61.0 GB at 3.4 MB/s, ETA: 4h30m0s | P: 41 | S: 29
GID: ewYQowYoFkavfYTO

redacted - Downloading
[█▎           ] 10.06% , 6.1 GB of 60.9 GB at 2.9 MB/s, ETA: 5h30m0s | P: 30 | S: 20
GID: glDniqIKuXvLnJIW

redacted - Downloading
[████████████▍] 99.76% , 55.2 GB of 55.3 GB at 3.0 MB/s, ETA: 44s | P: 30 | S: 21
GID: KCNPDjXnIRmnCLLz

Alloc: 161.9 MB | TAlloc: 147.6 GB | GC: 1508 | GR: 394 | TH: 11 | CPU: 16.59% | DL: 9.2 MB | UP: 0 B

Anacrolix/torrent version: v1.47.0 torrents.zip

anacrolix commented 1 year ago

Thanks for reporting this. Looks like there's no actual checking that chunks are valid when received. It's likely a buggy or malicious peer causing this. You can send the infohash to me privately if you wish and I might debug it more accurately. Either way, the method should return an error, and it should be handled in receiveChunk. The open question is whether I should check the bounds earlier in receiveChunk than when it's attempting to be written, and whether we should try to correct the situation in case the peer is buggy.

JaskaranSM commented 1 year ago

Heres the torrents that the client was downloading when this panic occured: torrents.zip

anacrolix commented 1 year ago

Thanks. I'm not able to reproduce this. There's a check at https://github.com/anacrolix/torrent/blob/3e0f34934df4f109b39b5e28e674b438732a7ab8/peerconn.go#L1439 that a received chunk is expected, so it would require that we send a bad request. I tested this by running GOPPROF=http godo -race -v -- ~/ags/torrent/cmd/torrent download --file RARBG.txt torrents/*.torrent using the provided zip. Failing some error elsewhere, there might be an off-by-one error somewhere deep in the requesting code to cause this failure. I'll keep testing, but any more info you have would be great.

JaskaranSM commented 1 year ago

Thanks, looks like fixed now :)