Line data Source code
1 : #if !FD_HAS_HOSTED 2 : #error "This target requires FD_HAS_HOSTED" 3 : #endif 4 : 5 : #include <assert.h> 6 : #include <stdio.h> 7 : #include <stdlib.h> 8 : 9 : #include "../../util/sanitize/fd_fuzz.h" 10 : #include "../../util/fd_util.h" 11 : #include "fd_shred.h" 12 : 13 : int 14 : LLVMFuzzerInitialize( int * argc, 15 18 : char *** argv ) { 16 : /* Set up shell without signal handlers */ 17 18 : putenv( "FD_LOG_BACKTRACE=0" ); 18 18 : fd_boot( argc, argv ); 19 18 : atexit( fd_halt ); 20 18 : return 0; 21 18 : } 22 : 23 : int 24 : LLVMFuzzerTestOneInput( uchar const * data, 25 : ulong size ) { 26 : 27 : fd_shred_t const * shred = fd_shred_parse( data, size ); 28 : if( shred==NULL ) return 0; 29 : 30 : # define BOUNDS_CHECK( ptr, sz ) \ 31 : do { \ 32 : ulong b0 = (ulong)(ptr); \ 33 : ulong b1 = b0 + (ulong)(sz); \ 34 : if( b0!=b1 ) { \ 35 : assert( b0<b1 ); \ 36 : assert( b0>=(ulong)data ); \ 37 : assert( b1<=(ulong)(data+size) ); \ 38 : } \ 39 : } while(0); 40 : # define BOUNDS_CHECK_OFF( off, sz ) BOUNDS_CHECK( (ulong)shred + (off), (sz) ) 41 : 42 : uchar variant = (uchar)shred->variant; 43 : uchar type = (uchar)fd_shred_type( variant ); 44 : 45 : assert( fd_shred_sz ( shred ) <= size ); 46 : assert( fd_shred_header_sz ( variant ) <= size ); 47 : assert( fd_shred_payload_sz( shred ) <= size ); 48 : assert( fd_shred_merkle_sz ( variant ) <= size ); 49 : 50 : switch( type ) { 51 : 52 : case FD_SHRED_TYPE_LEGACY_CODE: 53 : FD_FUZZ_MUST_BE_COVERED; 54 : assert( fd_shred_is_code ( type ) ); 55 : assert( !fd_shred_is_data ( type ) ); 56 : assert( !fd_shred_merkle_cnt ( variant ) ); 57 : assert( !fd_shred_is_chained ( type ) ); 58 : assert( !fd_shred_is_resigned( type ) ); 59 : BOUNDS_CHECK( fd_shred_code_payload( shred ), fd_shred_payload_sz( shred ) ); 60 : break; 61 : 62 : case FD_SHRED_TYPE_LEGACY_DATA: 63 : FD_FUZZ_MUST_BE_COVERED; 64 : assert( !fd_shred_is_code ( type ) ); 65 : assert( fd_shred_is_data ( type ) ); 66 : assert( !fd_shred_merkle_cnt ( variant ) ); 67 : assert( !fd_shred_is_chained ( type ) ); 68 : assert( !fd_shred_is_resigned( type ) ); 69 : BOUNDS_CHECK( fd_shred_data_payload( shred ), fd_shred_payload_sz( shred ) ); 70 : break; 71 : 72 : case FD_SHRED_TYPE_MERKLE_CODE: 73 : FD_FUZZ_MUST_BE_COVERED; 74 : assert( fd_shred_is_code ( type ) ); 75 : assert( !fd_shred_is_data ( type ) ); 76 : //assert( fd_shred_merkle_cnt ( variant ) ); 77 : assert( !fd_shred_is_chained ( type ) ); 78 : assert( !fd_shred_is_resigned( type ) ); 79 : BOUNDS_CHECK( fd_shred_code_payload( shred ), fd_shred_payload_sz( shred ) ); 80 : BOUNDS_CHECK( fd_shred_merkle_nodes( shred ), fd_shred_merkle_sz( variant ) ); 81 : break; 82 : 83 : case FD_SHRED_TYPE_MERKLE_DATA: 84 : FD_FUZZ_MUST_BE_COVERED; 85 : assert( !fd_shred_is_code ( type ) ); 86 : assert( fd_shred_is_data ( type ) ); 87 : //assert( fd_shred_merkle_cnt ( variant ) ); 88 : assert( !fd_shred_is_chained ( type ) ); 89 : assert( !fd_shred_is_resigned( type ) ); 90 : BOUNDS_CHECK( fd_shred_data_payload( shred ), fd_shred_payload_sz( shred ) ); 91 : BOUNDS_CHECK( fd_shred_merkle_nodes( shred ), fd_shred_merkle_sz( variant ) ); 92 : break; 93 : 94 : case FD_SHRED_TYPE_MERKLE_CODE_CHAINED: 95 : FD_FUZZ_MUST_BE_COVERED; 96 : assert( fd_shred_is_code ( type ) ); 97 : assert( !fd_shred_is_data ( type ) ); 98 : //assert( fd_shred_merkle_cnt ( variant ) ); 99 : assert( fd_shred_is_chained ( type ) ); 100 : assert( !fd_shred_is_resigned( type ) ); 101 : BOUNDS_CHECK ( fd_shred_code_payload( shred ), fd_shred_payload_sz( shred ) ); 102 : BOUNDS_CHECK ( fd_shred_merkle_nodes( shred ), fd_shred_merkle_sz( variant ) ); 103 : BOUNDS_CHECK_OFF( fd_shred_chain_offset( variant ), FD_SHRED_MERKLE_ROOT_SZ ); 104 : break; 105 : 106 : case FD_SHRED_TYPE_MERKLE_DATA_CHAINED: 107 : FD_FUZZ_MUST_BE_COVERED; 108 : assert( !fd_shred_is_code ( type ) ); 109 : assert( fd_shred_is_data ( type ) ); 110 : //assert( fd_shred_merkle_cnt ( variant ) ); 111 : assert( fd_shred_is_chained ( type ) ); 112 : assert( !fd_shred_is_resigned( type ) ); 113 : BOUNDS_CHECK ( fd_shred_data_payload( shred ), fd_shred_payload_sz( shred ) ); 114 : BOUNDS_CHECK ( fd_shred_merkle_nodes( shred ), fd_shred_merkle_sz( variant ) ); 115 : BOUNDS_CHECK_OFF( fd_shred_chain_offset( variant ), FD_SHRED_MERKLE_ROOT_SZ ); 116 : break; 117 : 118 : case FD_SHRED_TYPE_MERKLE_CODE_CHAINED_RESIGNED: 119 : FD_FUZZ_MUST_BE_COVERED; 120 : assert( fd_shred_is_code ( type ) ); 121 : assert( !fd_shred_is_data ( type ) ); 122 : //assert( fd_shred_merkle_cnt ( variant ) ); 123 : assert( fd_shred_is_chained ( type ) ); 124 : assert( fd_shred_is_resigned( type ) ); 125 : BOUNDS_CHECK ( fd_shred_code_payload( shred ), fd_shred_payload_sz( shred ) ); 126 : BOUNDS_CHECK ( fd_shred_merkle_nodes( shred ), fd_shred_merkle_sz( variant ) ); 127 : BOUNDS_CHECK_OFF( fd_shred_chain_offset( variant ), FD_SHRED_MERKLE_ROOT_SZ ); 128 : BOUNDS_CHECK_OFF( fd_shred_retransmitter_sig_off( shred ), FD_SHRED_SIGNATURE_SZ ); 129 : break; 130 : 131 : case FD_SHRED_TYPE_MERKLE_DATA_CHAINED_RESIGNED: 132 : FD_FUZZ_MUST_BE_COVERED; 133 : assert( !fd_shred_is_code ( type ) ); 134 : assert( fd_shred_is_data ( type ) ); 135 : //assert( fd_shred_merkle_cnt ( variant ) ); 136 : assert( fd_shred_is_chained ( type ) ); 137 : assert( fd_shred_is_resigned( type ) ); 138 : BOUNDS_CHECK ( fd_shred_data_payload( shred ), fd_shred_payload_sz( shred ) ); 139 : BOUNDS_CHECK ( fd_shred_merkle_nodes( shred ), fd_shred_merkle_sz( variant ) ); 140 : BOUNDS_CHECK_OFF( fd_shred_chain_offset( variant ), FD_SHRED_MERKLE_ROOT_SZ ); 141 : BOUNDS_CHECK_OFF( fd_shred_retransmitter_sig_off( shred ), FD_SHRED_SIGNATURE_SZ ); 142 : break; 143 : 144 : default: 145 : /* unknown variant */ 146 : abort(); 147 : break; 148 : } 149 : 150 : # undef BOUNDS_CHECK 151 : # undef BOUNDS_CHECK_OFF 152 : 153 : FD_FUZZ_MUST_BE_COVERED; 154 : return 0; 155 : }