Ignore:
Timestamp:
Jan 31, 2008, 2:24:43 AM (14 years ago)
Author:
charles
Message:

#667: remote crash exploit in bencode parser

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/bencode-test.c

    r4869 r4876  
    44#include "utils.h" /* tr_free */
    55
    6 #define VERBOSE 1
     6#define VERBOSE 0
    77
    88int test = 0;
     
    3030    /* good int string */
    3131    snprintf( (char*)buf, sizeof( buf ), "i64e" );
    32     err = tr_bencParseInt( buf, 4, &end, &val );
     32    err = tr_bencParseInt( buf, buf+4, &end, &val );
    3333    check( err == 0 );
    3434    check( val == 64 );
     
    3838    end = NULL;
    3939    val = 888;
    40     err = tr_bencParseInt( buf, 3, &end, &val );
     40    err = tr_bencParseInt( buf, buf+3, &end, &val );
    4141    check( err == TR_ERROR );
    4242    check( val == 888 );
     
    4444
    4545    /* empty buffer */
    46     err = tr_bencParseInt( buf, 0, &end, &val );
     46    err = tr_bencParseInt( buf, buf+0, &end, &val );
    4747    check( err == TR_ERROR );
    4848    check( val == 888 );
     
    5151    /* bad number */
    5252    snprintf( (char*)buf, sizeof( buf ), "i6z4e" );
    53     err = tr_bencParseInt( buf, 4, &end, &val );
     53    err = tr_bencParseInt( buf, buf+5, &end, &val );
    5454    check( err == TR_ERROR );
    5555    check( val == 888 );
     
    5858    /* negative number */
    5959    snprintf( (char*)buf, sizeof( buf ), "i-3e" );
    60     err = tr_bencParseInt( buf, 4, &end, &val );
     60    err = tr_bencParseInt( buf, buf+4, &end, &val );
    6161    check( err == TR_OK );
    6262    check( val == -3 );
     
    6565    /* zero */
    6666    snprintf( (char*)buf, sizeof( buf ), "i0e" );
    67     err = tr_bencParseInt( buf, 4, &end, &val );
     67    err = tr_bencParseInt( buf, buf+4, &end, &val );
    6868    check( err == TR_OK );
    6969    check( val == 0 );
     
    7474    end = NULL;
    7575    snprintf( (char*)buf, sizeof( buf ), "i04e" );
    76     err = tr_bencParseInt( buf, 4, &end, &val );
     76    err = tr_bencParseInt( buf, buf+4, &end, &val );
    7777    check( err == TR_ERROR );
    7878    check( val == 0 );
     
    9393    /* good string */
    9494    snprintf( (char*)buf, sizeof( buf ), "4:boat" );
    95     err = tr_bencParseStr( buf, 6, &end, &str, &len );
     95    err = tr_bencParseStr( buf, buf+6, &end, &str, &len );
    9696    check( err == TR_OK );
    9797    check( !strcmp( (char*)str, "boat" ) );
     
    104104
    105105    /* string goes past end of buffer */
    106     err = tr_bencParseStr( buf, 5, &end, &str, &len );
     106    err = tr_bencParseStr( buf, buf+5, &end, &str, &len );
    107107    check( err == TR_ERROR );
    108108    check( str == NULL );
     
    112112    /* empty string */
    113113    snprintf( (char*)buf, sizeof( buf ), "0:" );
    114     err = tr_bencParseStr( buf, 2, &end, &str, &len );
     114    err = tr_bencParseStr( buf, buf+2, &end, &str, &len );
    115115    check( err == TR_OK );
    116116    check( !*str );
     
    124124    /* short string */
    125125    snprintf( (char*)buf, sizeof( buf ), "3:boat" );
    126     err = tr_bencParseStr( buf, 6, &end, &str, &len );
     126    err = tr_bencParseStr( buf, buf+6, &end, &str, &len );
    127127    check( err == TR_OK );
    128128    check( !strcmp( (char*)str, "boa" ) );
     
    136136    return 0;
    137137}
    138  
     138
     139static int
     140testParse( void )
     141{
     142    benc_val_t val;
     143    benc_val_t * child;
     144    benc_val_t * child2;
     145    uint8_t buf[512];
     146    const uint8_t * end;
     147    int err;
     148    int len;
     149    char * saved;
     150
     151    snprintf( (char*)buf, sizeof( buf ), "i64e" );
     152    err = tr_bencParse( buf, buf + sizeof( buf ), &val, &end );
     153    check( !err );
     154    check( tr_bencIsInt( &val ) );
     155    check( tr_bencGetInt( &val ) == 64 );
     156    check( end == buf + 4 );
     157    tr_bencFree( &val );
     158
     159    snprintf( (char*)buf, sizeof( buf ), "li64ei32ei16ee" );
     160    err = tr_bencParse( buf, buf + sizeof( buf ), &val, &end );
     161    check( !err );
     162    check( tr_bencIsList( &val ) );
     163    check( end == buf + strlen( (char*)buf ) );
     164    check( val.val.l.count == 3 );
     165    check( tr_bencGetInt( &val.val.l.vals[0] ) == 64 );
     166    check( tr_bencGetInt( &val.val.l.vals[1] ) == 32 );
     167    check( tr_bencGetInt( &val.val.l.vals[2] ) == 16 );
     168    saved = tr_bencSave( &val, &len );
     169    check( !strcmp( saved, (char*)buf ) );
     170    tr_free( saved );
     171    tr_bencFree( &val );
     172
     173    end = NULL;
     174    snprintf( (char*)buf, sizeof( buf ), "lllee" );
     175    err = tr_bencParse( buf, buf + strlen( (char*)buf ), &val , &end );
     176    check( err );
     177    check( end == NULL );
     178
     179    end = NULL;
     180    snprintf( (char*)buf, sizeof( buf ), "le" );
     181    err = tr_bencParse( buf, buf + sizeof( buf ), &val , &end );
     182    check( !err );
     183    check( end == buf + 2 );
     184    saved = tr_bencSave( &val, &len );
     185    check( !strcmp( saved, "le" ) );
     186    tr_free( saved );
     187    tr_bencFree( &val );
     188
     189    end = NULL;
     190    snprintf( (char*)buf, sizeof( buf ), "llleee" );
     191    err = tr_bencParse( buf, buf + sizeof( buf ), &val , &end );
     192    check( !err );
     193    check( end == buf + 6 );
     194    saved = tr_bencSave( &val, &len );
     195    check( !strcmp( saved, "llleee" ) );
     196    tr_free( saved );
     197    tr_bencFree( &val );
     198
     199    /* nested containers
     200     * parse an unsorted dict
     201     * save as a sorted dict */
     202    end = NULL;
     203    snprintf( (char*)buf, sizeof( buf ), "lld1:bi32e1:ai64eeee" );
     204    err = tr_bencParse( buf, buf + sizeof( buf ), &val, &end );
     205    check( !err );
     206    check( end == buf + strlen( (const char*)buf ) );
     207    check( tr_bencIsList( &val ) );
     208    check(( child = tr_bencListGetNthChild( &val, 0 )));
     209    check( tr_bencIsList( child ) );
     210    check(( child2 = tr_bencListGetNthChild( child, 0 )));
     211    check( tr_bencIsDict( child2 ) );
     212    saved = tr_bencSave( &val, &len );
     213    check( !strcmp( saved, "lld1:ai64e1:bi32eeee" ) );
     214    tr_free( saved );
     215    tr_bencFree( &val );
     216
     217    return 0;
     218}
     219
     220static int
     221testStackSmash( void )
     222{
     223    int i;
     224    int len;
     225    int depth;
     226    int err;
     227    uint8_t * in;
     228    const uint8_t * end;
     229    benc_val_t val;
     230    char * saved;
     231
     232    depth = 1000000;
     233    in = tr_new( uint8_t, depth*2 + 1 );
     234    for( i=0; i<depth; ++i ) {
     235        in[i] = 'l';
     236        in[depth+i] = 'e';
     237    }
     238    in[depth*2] = '\0';
     239    err = tr_bencParse( in, in+(depth*2), &val, &end );
     240    check( !err );
     241    check( tr_bencIsList( &val ) );
     242    check( end == in+(depth*2) );
     243    saved = tr_bencSave( &val, &len );
     244    check( !strcmp( saved, (char*)in ) );
     245    tr_free( in );
     246    tr_free( saved );
     247    tr_bencFree( &val );
     248
     249    return 0;
     250}
     251
     252
    139253int
    140254main( void )
     
    142256    int i;
    143257
    144     if(( i = testInt( ) ))
    145         return i;
    146 
    147     if(( i = testStr( ) ))
    148         return i;
    149 
    150     return 0;
    151 }
     258    if(( i = testInt( )))
     259        return i;
     260
     261    if(( i = testStr( )))
     262        return i;
     263
     264    if(( i = testParse( )))
     265        return i;
     266
     267    if(( i = testStackSmash( )))
     268        return i;
     269
     270    return 0;
     271}
Note: See TracChangeset for help on using the changeset viewer.