Check all offsets and lengths received from the peer before using them.

This commit is contained in:
Josh Elsasser 2007-03-06 00:49:35 +00:00
parent e9b4fd8aff
commit fc76c65794
1 changed files with 58 additions and 7 deletions

View File

@ -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 );
} }