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 : fd_log_level_core_set(3); /* crash on warning log */ 21 18 : return 0; 22 18 : } 23 : 24 : int 25 : LLVMFuzzerTestOneInput( uchar const * data, 26 : ulong size ) { 27 : 28 : fd_shred_t const * shred = fd_shred_parse( data, size ); 29 : if( shred==NULL ) return 0; 30 : 31 : # define BOUNDS_CHECK( ptr, sz ) \ 32 : do { \ 33 : ulong b0 = (ulong)(ptr); \ 34 : ulong b1 = b0 + (ulong)(sz); \ 35 : if( b0!=b1 ) { \ 36 : assert( b0<b1 ); \ 37 : assert( b0>=(ulong)data ); \ 38 : assert( b1<=(ulong)(data+size) ); \ 39 : } \ 40 : } while(0); 41 : # define BOUNDS_CHECK_OFF( off, sz ) BOUNDS_CHECK( (ulong)shred + (off), (sz) ) 42 : 43 : uchar variant = (uchar)shred->variant; 44 : uchar type = (uchar)fd_shred_type( variant ); 45 : 46 : assert( fd_shred_sz ( shred ) <= size ); 47 : assert( fd_shred_header_sz ( variant ) <= size ); 48 : assert( fd_shred_payload_sz( shred ) <= size ); 49 : assert( fd_shred_merkle_sz ( variant ) <= size ); 50 : 51 : switch( type ) { 52 : 53 : case FD_SHRED_TYPE_LEGACY_CODE: 54 : FD_FUZZ_MUST_BE_COVERED; 55 : assert( fd_shred_is_code ( type ) ); 56 : assert( !fd_shred_is_data ( type ) ); 57 : assert( !fd_shred_merkle_cnt ( variant ) ); 58 : assert( !fd_shred_is_chained ( type ) ); 59 : assert( !fd_shred_is_resigned( type ) ); 60 : BOUNDS_CHECK( fd_shred_code_payload( shred ), fd_shred_payload_sz( shred ) ); 61 : break; 62 : 63 : case FD_SHRED_TYPE_LEGACY_DATA: 64 : FD_FUZZ_MUST_BE_COVERED; 65 : assert( !fd_shred_is_code ( type ) ); 66 : assert( fd_shred_is_data ( type ) ); 67 : assert( !fd_shred_merkle_cnt ( variant ) ); 68 : assert( !fd_shred_is_chained ( type ) ); 69 : assert( !fd_shred_is_resigned( type ) ); 70 : BOUNDS_CHECK( fd_shred_data_payload( shred ), fd_shred_payload_sz( shred ) ); 71 : break; 72 : 73 : case FD_SHRED_TYPE_MERKLE_CODE: 74 : FD_FUZZ_MUST_BE_COVERED; 75 : assert( fd_shred_is_code ( type ) ); 76 : assert( !fd_shred_is_data ( type ) ); 77 : //assert( fd_shred_merkle_cnt ( variant ) ); 78 : assert( !fd_shred_is_chained ( type ) ); 79 : assert( !fd_shred_is_resigned( type ) ); 80 : BOUNDS_CHECK( fd_shred_code_payload( shred ), fd_shred_payload_sz( shred ) ); 81 : BOUNDS_CHECK( fd_shred_merkle_nodes( shred ), fd_shred_merkle_sz( variant ) ); 82 : break; 83 : 84 : case FD_SHRED_TYPE_MERKLE_DATA: 85 : FD_FUZZ_MUST_BE_COVERED; 86 : assert( !fd_shred_is_code ( type ) ); 87 : assert( fd_shred_is_data ( type ) ); 88 : //assert( fd_shred_merkle_cnt ( variant ) ); 89 : assert( !fd_shred_is_chained ( type ) ); 90 : assert( !fd_shred_is_resigned( type ) ); 91 : BOUNDS_CHECK( fd_shred_data_payload( shred ), fd_shred_payload_sz( shred ) ); 92 : BOUNDS_CHECK( fd_shred_merkle_nodes( shred ), fd_shred_merkle_sz( variant ) ); 93 : break; 94 : 95 : case FD_SHRED_TYPE_MERKLE_CODE_CHAINED: 96 : FD_FUZZ_MUST_BE_COVERED; 97 : assert( fd_shred_is_code ( type ) ); 98 : assert( !fd_shred_is_data ( type ) ); 99 : //assert( fd_shred_merkle_cnt ( variant ) ); 100 : assert( fd_shred_is_chained ( type ) ); 101 : assert( !fd_shred_is_resigned( type ) ); 102 : BOUNDS_CHECK ( fd_shred_code_payload( shred ), fd_shred_payload_sz( shred ) ); 103 : BOUNDS_CHECK ( fd_shred_merkle_nodes( shred ), fd_shred_merkle_sz( variant ) ); 104 : BOUNDS_CHECK_OFF( fd_shred_chain_off( variant ), FD_SHRED_MERKLE_ROOT_SZ ); 105 : break; 106 : 107 : case FD_SHRED_TYPE_MERKLE_DATA_CHAINED: 108 : FD_FUZZ_MUST_BE_COVERED; 109 : assert( !fd_shred_is_code ( type ) ); 110 : assert( fd_shred_is_data ( type ) ); 111 : //assert( fd_shred_merkle_cnt ( variant ) ); 112 : assert( fd_shred_is_chained ( type ) ); 113 : assert( !fd_shred_is_resigned( type ) ); 114 : BOUNDS_CHECK ( fd_shred_data_payload( shred ), fd_shred_payload_sz( shred ) ); 115 : BOUNDS_CHECK ( fd_shred_merkle_nodes( shred ), fd_shred_merkle_sz( variant ) ); 116 : BOUNDS_CHECK_OFF( fd_shred_chain_off( variant ), FD_SHRED_MERKLE_ROOT_SZ ); 117 : break; 118 : 119 : case FD_SHRED_TYPE_MERKLE_CODE_CHAINED_RESIGNED: 120 : FD_FUZZ_MUST_BE_COVERED; 121 : assert( fd_shred_is_code ( type ) ); 122 : assert( !fd_shred_is_data ( type ) ); 123 : //assert( fd_shred_merkle_cnt ( variant ) ); 124 : assert( fd_shred_is_chained ( type ) ); 125 : assert( fd_shred_is_resigned( type ) ); 126 : BOUNDS_CHECK ( fd_shred_code_payload( shred ), fd_shred_payload_sz( shred ) ); 127 : BOUNDS_CHECK ( fd_shred_merkle_nodes( shred ), fd_shred_merkle_sz( variant ) ); 128 : BOUNDS_CHECK_OFF( fd_shred_chain_off( variant ), FD_SHRED_MERKLE_ROOT_SZ ); 129 : BOUNDS_CHECK_OFF( fd_shred_retransmitter_sig_off( shred ), FD_SHRED_SIGNATURE_SZ ); 130 : break; 131 : 132 : case FD_SHRED_TYPE_MERKLE_DATA_CHAINED_RESIGNED: 133 : FD_FUZZ_MUST_BE_COVERED; 134 : assert( !fd_shred_is_code ( type ) ); 135 : assert( fd_shred_is_data ( type ) ); 136 : //assert( fd_shred_merkle_cnt ( variant ) ); 137 : assert( fd_shred_is_chained ( type ) ); 138 : assert( fd_shred_is_resigned( type ) ); 139 : BOUNDS_CHECK ( fd_shred_data_payload( shred ), fd_shred_payload_sz( shred ) ); 140 : BOUNDS_CHECK ( fd_shred_merkle_nodes( shred ), fd_shred_merkle_sz( variant ) ); 141 : BOUNDS_CHECK_OFF( fd_shred_chain_off( variant ), FD_SHRED_MERKLE_ROOT_SZ ); 142 : BOUNDS_CHECK_OFF( fd_shred_retransmitter_sig_off( shred ), FD_SHRED_SIGNATURE_SZ ); 143 : break; 144 : 145 : default: 146 : /* unknown variant */ 147 : abort(); 148 : break; 149 : } 150 : 151 : # undef BOUNDS_CHECK 152 : # undef BOUNDS_CHECK_OFF 153 : 154 : FD_FUZZ_MUST_BE_COVERED; 155 : return 0; 156 : }