From 34b4d0b7f915b7f27f9fde6037a5ec55f7f945c8 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 9 Jul 2007 16:30:20 +0000 Subject: [PATCH] fix r2306 double-free crash reported by Gimp_, webaake --- libtransmission/list.c | 52 +++++++++++++++------------------- libtransmission/list.h | 18 ++++++------ libtransmission/peermessages.h | 2 +- libtransmission/peerparse.h | 5 ++-- 4 files changed, 35 insertions(+), 42 deletions(-) diff --git a/libtransmission/list.c b/libtransmission/list.c index bcdfa3862..1510216b3 100644 --- a/libtransmission/list.c +++ b/libtransmission/list.c @@ -12,29 +12,22 @@ #include "list.h" #include "utils.h" -int -tr_list_length( const tr_list_t * list ) -{ - int i = 0; - while( list ) { - ++i; - list = list->next; - } - return i; -} - -tr_list_t* -tr_list_alloc( void ) +static tr_list_t* +node_alloc( void ) { return tr_new0( tr_list_t, 1 ); } -void -tr_list_free1( tr_list_t* node ) +static void +node_free( tr_list_t* node ) { tr_free( node ); } +/*** +**** +***/ + void tr_list_free( tr_list_t* list ) { @@ -42,14 +35,14 @@ tr_list_free( tr_list_t* list ) { tr_list_t * node = list; list = list->next; - tr_list_free1( node ); + node_free( node ); } } tr_list_t* tr_list_prepend( tr_list_t * list, void * data ) { - tr_list_t * node = tr_list_alloc (); + tr_list_t * node = node_alloc (); node->data = data; node->next = list; if( list ) @@ -60,16 +53,18 @@ tr_list_prepend( tr_list_t * list, void * data ) tr_list_t* tr_list_append( tr_list_t * list, void * data ) { - tr_list_t * node = list; - tr_list_t * l = tr_list_alloc( ); - l->data = data; + tr_list_t * node = node_alloc( ); + node->data = data; if( !list ) - return l; - while( node->next ) - node = node->next; - node->next = l; - l->prev = node; - return list; + return node; + else { + tr_list_t * l = list; + while( l->next ) + l = l->next; + l->next = node; + node->prev = l; + return list; + } } tr_list_t* @@ -83,7 +78,7 @@ tr_list_find_data ( tr_list_t * list, const void * data ) } tr_list_t* -tr_list_remove( tr_list_t * list, const void * data ) +tr_list_remove_data ( tr_list_t * list, const void * data ) { tr_list_t * node = tr_list_find_data( list, data ); tr_list_t * prev = node ? node->prev : NULL; @@ -91,7 +86,7 @@ tr_list_remove( tr_list_t * list, const void * data ) if( prev ) prev->next = next; if( next ) next->prev = prev; if( list == node ) list = next; - tr_list_free1( node ); + node_free( node ); return list; } @@ -114,4 +109,3 @@ tr_list_foreach( tr_list_t * list, TrListForeachFunc func ) list = list->next; } } - diff --git a/libtransmission/list.h b/libtransmission/list.h index af7b413fb..4b1aebb82 100644 --- a/libtransmission/list.h +++ b/libtransmission/list.h @@ -19,20 +19,18 @@ typedef struct tr_list_s } tr_list_t; -void tr_list_free_1 ( void ); -void tr_list_free ( tr_list_t* ); -int tr_list_length ( const tr_list_t* ); -tr_list_t* tr_list_append ( tr_list_t*, void * data ); -tr_list_t* tr_list_prepend ( tr_list_t*, void * data ); -tr_list_t* tr_list_remove ( tr_list_t*, const void * data ); -tr_list_t* tr_list_pop ( tr_list_t*, void ** setme ); +void tr_list_free ( tr_list_t* ); +tr_list_t* tr_list_append ( tr_list_t*, void * data ); +tr_list_t* tr_list_prepend ( tr_list_t*, void * data ); +tr_list_t* tr_list_remove_data ( tr_list_t*, const void * data ); +tr_list_t* tr_list_pop ( tr_list_t*, void ** setme ); typedef int (*TrListCompareFunc)(const void * a, const void * b); -tr_list_t* tr_list_find ( tr_list_t*, TrListCompareFunc func, const void * b ); -tr_list_t* tr_list_find_data ( tr_list_t*, const void * data ); +tr_list_t* tr_list_find ( tr_list_t*, TrListCompareFunc func, const void * b ); +tr_list_t* tr_list_find_data ( tr_list_t*, const void * data ); typedef void (*TrListForeachFunc)(void *); -void tr_list_foreach( tr_list_t*, TrListForeachFunc func ); +void tr_list_foreach ( tr_list_t*, TrListForeachFunc func ); #endif /* TR_LIST_H */ diff --git a/libtransmission/peermessages.h b/libtransmission/peermessages.h index d372e840e..04ab34cf3 100644 --- a/libtransmission/peermessages.h +++ b/libtransmission/peermessages.h @@ -123,7 +123,7 @@ blockPending( tr_torrent_t * tor, r = (tr_request_t*) peer->outRequests->data; assert( r != NULL ); - peer->outRequests = tr_list_remove( peer->outRequests, r ); + peer->outRequests = tr_list_remove_data( peer->outRequests, r ); if( !tr_cpPieceIsComplete( tor->completion, r->index ) ) /* sanity clause */ { diff --git a/libtransmission/peerparse.h b/libtransmission/peerparse.h index 48e161738..eadbf002a 100644 --- a/libtransmission/peerparse.h +++ b/libtransmission/peerparse.h @@ -417,8 +417,9 @@ static inline int parseCancel( tr_torrent_t * tor, tr_peer_t * peer, req.begin = begin; req.length = length; while(( l = tr_list_find( peer->outRequests, reqCompare, &req ) )) { - tr_free( l->data ); - peer->outRequests = tr_list_remove( peer->outRequests, l ); + tr_request_t * r = (tr_request_t *) l->data; + peer->outRequests = tr_list_remove_data( peer->outRequests, r ); + tr_free( r ); } return TR_OK;