Line data Source code
1 : #include <stddef.h> 2 : #include <stdlib.h> 3 : #include <string.h> 4 : #include <stdio.h> 5 : 6 : #include "../../../util/fd_util.h" 7 : #include "../../../util/sanitize/fd_fuzz.h" 8 : #include "fd_quic_transport_params.h" 9 : 10 : int 11 : LLVMFuzzerInitialize( int * argc, 12 12 : char *** argv ) { 13 : /* Set up shell without signal handlers */ 14 12 : putenv( "FD_LOG_BACKTRACE=0" ); 15 12 : fd_boot( argc, argv ); 16 12 : atexit( fd_halt ); 17 12 : fd_log_level_core_set(3); /* crash on warning log */ 18 : 19 12 : return 0; 20 12 : } 21 : 22 : int 23 : LLVMFuzzerTestOneInput( uchar const * data, 24 : ulong size ) { 25 : fd_quic_transport_params_t tp1 = {0}; 26 : int rc = fd_quic_decode_transport_params( &tp1, data, size ); 27 : if( rc==0 ) { 28 : FD_FUZZ_MUST_BE_COVERED; 29 : 30 : /* Encode decoded params */ 31 : uchar buf1[ 2048 ]; 32 : ulong sz1 = fd_quic_encode_transport_params( buf1, sizeof(buf1), &tp1 ); 33 : FD_TEST( sz1 <= sizeof(buf1) ); 34 : 35 : /* Decode what we just encoded */ 36 : fd_quic_transport_params_t tp2 = (fd_quic_transport_params_t){0}; 37 : int rc2 = fd_quic_decode_transport_params( &tp2, buf1, sz1 ); 38 : FD_TEST( rc2==0 ); 39 : 40 : /* Compare pretty-printed dumps instead of raw struct bytes */ 41 : char * s1 = NULL; size_t n1 = 0UL; FILE * m1 = open_memstream( &s1, &n1 ); 42 : char * s2 = NULL; size_t n2 = 0UL; FILE * m2 = open_memstream( &s2, &n2 ); 43 : FD_TEST( m1 && m2 ); 44 : 45 : fd_quic_dump_transport_params( &tp1, m1 ); 46 : fd_quic_dump_transport_params( &tp2, m2 ); 47 : fflush( m1 ); fflush( m2 ); 48 : fclose( m1 ); fclose( m2 ); 49 : 50 : if( FD_UNLIKELY( strcmp( s1, s2 )!=0 ) ) { 51 : /* Why not memcmp of tp1, tp2 ? 52 : - Duplicate parameter overwrite: The decoder accepts repeated 53 : transport parameters and "last one wins." With input like 54 : id=0x00 (original_destination_connection_id) first with length 55 : 2, then again with length 0, the second parse sets *_len=0 but 56 : leaves the prior bytes in the fixed-size array. 57 : - Stale bytes: For CONN_ID, TOKEN, and PREFERRED_ADDRESS types, 58 : the parse macros only memcpy the first sz bytes and set *_len, 59 : but do not clear the rest of the backing array. This leaves 60 : stale data when a shorter (or zero-length) duplicate param 61 : appears. */ 62 : FD_LOG_NOTICE(( "tp1 dump:\n%s", s1 )); 63 : FD_LOG_NOTICE(( "tp2 dump:\n%s", s2 )); 64 : FD_LOG_HEXDUMP_NOTICE(( "tp1", &tp1, sizeof(fd_quic_transport_params_t) )); 65 : FD_LOG_HEXDUMP_NOTICE(( "tp2", &tp2, sizeof(fd_quic_transport_params_t) )); 66 : free( s1 ); 67 : free( s2 ); 68 : FD_LOG_ERR(( "transport params dump mismatch after encode->decode" )); 69 : } 70 : 71 : free( s1 ); 72 : free( s2 ); 73 : } 74 : 75 : return 0; 76 : }