From b9adf279cafd683ce6b694027c8ed9dde5455f0c Mon Sep 17 00:00:00 2001 From: Mike Gelfand Date: Sun, 5 Jul 2015 07:54:46 +0000 Subject: [PATCH] #5912: Prevent completed pieces modification by webseeds (patch by cfpp2p) This avoids blocks corruption in case webseed provides bad data. As explained by cfpp2p, "The requirements to reproduce are at least one webseed that sends corrupt block(s), and at least one other peer (webseed or regular peer) that sends correct data for the same block. Then a peer with correct block sends the block and transmission accepts and verifies that block as good. But then the webseed thread comes around and the same block is downloaded from the webseed that sends a bad block which is then written even though the piece was previously deemed complete." --- libtransmission/webseed.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/libtransmission/webseed.c b/libtransmission/webseed.c index 338424b43..9d6588f97 100644 --- a/libtransmission/webseed.c +++ b/libtransmission/webseed.c @@ -162,14 +162,17 @@ write_block_func (void * vdata) tr_cache * cache = data->session->cache; const tr_piece_index_t piece = data->piece_index; - while (len > 0) + if (!tr_torrentPieceIsComplete (tor, piece)) { - const uint32_t bytes_this_pass = MIN (len, block_size); - tr_cacheWriteBlock (cache, tor, piece, offset_end - len, bytes_this_pass, buf); - len -= bytes_this_pass; - } + while (len > 0) + { + const uint32_t bytes_this_pass = MIN (len, block_size); + tr_cacheWriteBlock (cache, tor, piece, offset_end - len, bytes_this_pass, buf); + len -= bytes_this_pass; + } - fire_client_got_blocks (tor, w, data->block_index, data->count); + fire_client_got_blocks (tor, w, data->block_index, data->count); + } } evbuffer_free (buf); @@ -422,7 +425,7 @@ web_response_func (tr_session * session, } else { - if (buf_len) + if (buf_len && !tr_torrentPieceIsComplete (tor, t->piece_index)) { /* on_content_changed () will not write a block if it is smaller than the torrent's block size, i.e. the torrent's very last block */