Check all offsets and lengths received from the peer before using them.
This commit is contained in:
parent
e9b4fd8aff
commit
fc76c65794
|
@ -90,6 +90,7 @@ static inline int parseInterested( tr_peer_t * peer, int len,
|
||||||
static inline int parseHave( tr_torrent_t * tor, tr_peer_t * peer,
|
static inline int parseHave( tr_torrent_t * tor, tr_peer_t * peer,
|
||||||
uint8_t * p, int len )
|
uint8_t * p, int len )
|
||||||
{
|
{
|
||||||
|
tr_info_t * inf = &tor->info;
|
||||||
uint32_t piece;
|
uint32_t piece;
|
||||||
|
|
||||||
if( len != 4 )
|
if( len != 4 )
|
||||||
|
@ -99,17 +100,22 @@ static inline int parseHave( tr_torrent_t * tor, tr_peer_t * peer,
|
||||||
}
|
}
|
||||||
|
|
||||||
TR_NTOHL( p, piece );
|
TR_NTOHL( p, piece );
|
||||||
|
if( ( uint32_t )inf->pieceCount <= piece )
|
||||||
|
{
|
||||||
|
peer_dbg( "GET have, invalid piece" );
|
||||||
|
return TR_ERROR_ASSERT;
|
||||||
|
}
|
||||||
|
|
||||||
peer_dbg( "GET have %d", piece );
|
peer_dbg( "GET have %d", piece );
|
||||||
|
|
||||||
if( !peer->bitfield )
|
if( !peer->bitfield )
|
||||||
{
|
{
|
||||||
peer->bitfield = tr_bitfieldNew( tor->info.pieceCount );
|
peer->bitfield = tr_bitfieldNew( inf->pieceCount );
|
||||||
}
|
}
|
||||||
if( !tr_bitfieldHas( peer->bitfield, piece ) )
|
if( !tr_bitfieldHas( peer->bitfield, piece ) )
|
||||||
{
|
{
|
||||||
peer->pieceCount++;
|
peer->pieceCount++;
|
||||||
peer->progress = (float) peer->pieceCount / tor->info.pieceCount;
|
peer->progress = (float) peer->pieceCount / inf->pieceCount;
|
||||||
}
|
}
|
||||||
tr_bitfieldAdd( peer->bitfield, piece );
|
tr_bitfieldAdd( peer->bitfield, piece );
|
||||||
updateInterest( tor, peer );
|
updateInterest( tor, peer );
|
||||||
|
@ -174,8 +180,10 @@ static inline int parseBitfield( tr_torrent_t * tor, tr_peer_t * peer,
|
||||||
return TR_OK;
|
return TR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int parseRequest( tr_peer_t * peer, uint8_t * p, int len )
|
static inline int parseRequest( tr_torrent_t * tor, tr_peer_t * peer,
|
||||||
|
uint8_t * p, int len )
|
||||||
{
|
{
|
||||||
|
tr_info_t * inf = &tor->info;
|
||||||
int index, begin, length;
|
int index, begin, length;
|
||||||
tr_request_t * r;
|
tr_request_t * r;
|
||||||
|
|
||||||
|
@ -196,6 +204,17 @@ static inline int parseRequest( tr_peer_t * peer, uint8_t * p, int len )
|
||||||
TR_NTOHL( &p[4], begin );
|
TR_NTOHL( &p[4], begin );
|
||||||
TR_NTOHL( &p[8], length );
|
TR_NTOHL( &p[8], length );
|
||||||
|
|
||||||
|
if( inf->pieceCount <= index )
|
||||||
|
{
|
||||||
|
peer_dbg( "GET request, invalid index" );
|
||||||
|
return TR_ERROR_ASSERT;
|
||||||
|
}
|
||||||
|
if( tr_pieceSize( index ) < begin + length )
|
||||||
|
{
|
||||||
|
peer_dbg( "GET request, invalid begin/length" );
|
||||||
|
return TR_ERROR_ASSERT;
|
||||||
|
}
|
||||||
|
|
||||||
peer_dbg( "GET request %d/%d (%d bytes)",
|
peer_dbg( "GET request %d/%d (%d bytes)",
|
||||||
index, begin, length );
|
index, begin, length );
|
||||||
|
|
||||||
|
@ -268,10 +287,29 @@ static inline void updateRequests( tr_torrent_t * tor, tr_peer_t * peer,
|
||||||
static inline int parsePiece( tr_torrent_t * tor, tr_peer_t * peer,
|
static inline int parsePiece( tr_torrent_t * tor, tr_peer_t * peer,
|
||||||
uint8_t * p, int len )
|
uint8_t * p, int len )
|
||||||
{
|
{
|
||||||
|
tr_info_t * inf = &tor->info;
|
||||||
int index, begin, block, i, ret;
|
int index, begin, block, i, ret;
|
||||||
|
|
||||||
|
if( 8 > len )
|
||||||
|
{
|
||||||
|
peer_dbg( "GET piece, too short (8 > %i)", len );
|
||||||
|
return TR_ERROR_ASSERT;
|
||||||
|
}
|
||||||
|
|
||||||
TR_NTOHL( p, index );
|
TR_NTOHL( p, index );
|
||||||
TR_NTOHL( &p[4], begin );
|
TR_NTOHL( &p[4], begin );
|
||||||
|
|
||||||
|
if( inf->pieceCount <= index )
|
||||||
|
{
|
||||||
|
peer_dbg( "GET piece, invalid index" );
|
||||||
|
return TR_ERROR_ASSERT;
|
||||||
|
}
|
||||||
|
if( tr_pieceSize( index ) < begin + len - 8 )
|
||||||
|
{
|
||||||
|
peer_dbg( "GET piece, invalid begin/length" );
|
||||||
|
return TR_ERROR_ASSERT;
|
||||||
|
}
|
||||||
|
|
||||||
block = tr_block( index, begin );
|
block = tr_block( index, begin );
|
||||||
|
|
||||||
peer_dbg( "GET piece %d/%d (%d bytes)",
|
peer_dbg( "GET piece %d/%d (%d bytes)",
|
||||||
|
@ -295,7 +333,7 @@ static inline int parsePiece( tr_torrent_t * tor, tr_peer_t * peer,
|
||||||
/* Set blame/credit for this piece */
|
/* Set blame/credit for this piece */
|
||||||
if( !peer->blamefield )
|
if( !peer->blamefield )
|
||||||
{
|
{
|
||||||
peer->blamefield = tr_bitfieldNew( tor->info.pieceCount );
|
peer->blamefield = tr_bitfieldNew( inf->pieceCount );
|
||||||
}
|
}
|
||||||
tr_bitfieldAdd( peer->blamefield, index );
|
tr_bitfieldAdd( peer->blamefield, index );
|
||||||
|
|
||||||
|
@ -338,8 +376,10 @@ static inline int parsePiece( tr_torrent_t * tor, tr_peer_t * peer,
|
||||||
return TR_OK;
|
return TR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int parseCancel( tr_peer_t * peer, uint8_t * p, int len )
|
static inline int parseCancel( tr_torrent_t * tor, tr_peer_t * peer,
|
||||||
|
uint8_t * p, int len )
|
||||||
{
|
{
|
||||||
|
tr_info_t * inf = &tor->info;
|
||||||
int index, begin, length;
|
int index, begin, length;
|
||||||
int i;
|
int i;
|
||||||
tr_request_t * r;
|
tr_request_t * r;
|
||||||
|
@ -354,6 +394,17 @@ static inline int parseCancel( tr_peer_t * peer, uint8_t * p, int len )
|
||||||
TR_NTOHL( &p[4], begin );
|
TR_NTOHL( &p[4], begin );
|
||||||
TR_NTOHL( &p[8], length );
|
TR_NTOHL( &p[8], length );
|
||||||
|
|
||||||
|
if( inf->pieceCount <= index )
|
||||||
|
{
|
||||||
|
peer_dbg( "GET cancel, invalid index" );
|
||||||
|
return TR_ERROR_ASSERT;
|
||||||
|
}
|
||||||
|
if( tr_pieceSize( index ) < begin + length )
|
||||||
|
{
|
||||||
|
peer_dbg( "GET cancel, invalid begin/length" );
|
||||||
|
return TR_ERROR_ASSERT;
|
||||||
|
}
|
||||||
|
|
||||||
peer_dbg( "GET cancel %d/%d (%d bytes)",
|
peer_dbg( "GET cancel %d/%d (%d bytes)",
|
||||||
index, begin, length );
|
index, begin, length );
|
||||||
|
|
||||||
|
@ -413,11 +464,11 @@ static inline int parseMessage( tr_torrent_t * tor, tr_peer_t * peer,
|
||||||
case PEER_MSG_BITFIELD:
|
case PEER_MSG_BITFIELD:
|
||||||
return parseBitfield( tor, peer, p, len );
|
return parseBitfield( tor, peer, p, len );
|
||||||
case PEER_MSG_REQUEST:
|
case PEER_MSG_REQUEST:
|
||||||
return parseRequest( peer, p, len );
|
return parseRequest( tor, peer, p, len );
|
||||||
case PEER_MSG_PIECE:
|
case PEER_MSG_PIECE:
|
||||||
return parsePiece( tor, peer, p, len );
|
return parsePiece( tor, peer, p, len );
|
||||||
case PEER_MSG_CANCEL:
|
case PEER_MSG_CANCEL:
|
||||||
return parseCancel( peer, p, len );
|
return parseCancel( tor, peer, p, len );
|
||||||
case PEER_MSG_PORT:
|
case PEER_MSG_PORT:
|
||||||
return parsePort( peer, p, len );
|
return parsePort( peer, p, len );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue