Line data Source code
1 : #if !FD_HAS_HOSTED 2 : #error "This target requires FD_HAS_HOSTED" 3 : #endif 4 : 5 : 6 : #include "fd_grpc_client.h" 7 : #include "fd_grpc_client_private.h" 8 : #include "../../util/fd_util.h" 9 : 10 : uchar client_mem[2 << 17] __attribute__((aligned(128))); 11 : ulong const buf_max = 4096UL; 12 : 13 : static void 14 : cb_rx_start( void *app_ctx, 15 0 : ulong request_ctx ) { 16 0 : (void) app_ctx; 17 0 : (void) request_ctx; 18 0 : } 19 : 20 : static void 21 : cb_rx_end( void *app_ctx, 22 : ulong request_ctx, 23 0 : fd_grpc_resp_hdrs_t *resp_hdrs ) { 24 0 : (void) app_ctx; 25 0 : (void) request_ctx; 26 0 : (void) resp_hdrs; 27 0 : } 28 : 29 : static void 30 : cb_rx_timeout( void *app_ctx, 31 : ulong request_ctx, 32 0 : int deadline_kind ) { 33 0 : (void) app_ctx; 34 0 : (void) request_ctx; 35 0 : (void) deadline_kind; 36 0 : } 37 : 38 : fd_grpc_client_callbacks_t callbacks = { 39 : .rx_start = cb_rx_start, 40 : .rx_end = cb_rx_end, 41 : .rx_timeout = cb_rx_timeout, 42 : }; 43 : 44 : static void 45 0 : test_grpc_client_mock_conn( fd_grpc_client_t *client ) { 46 0 : client->ssl_hs_done = 1; 47 0 : client->h2_hs_done = 1; 48 0 : client->conn->flags = 0; 49 0 : } 50 : 51 : int 52 : LLVMFuzzerInitialize( int *argc, 53 0 : char ***argv ) { 54 : /* Set up shell without signal handlers */ 55 0 : putenv( "FD_LOG_BACKTRACE=0" ); 56 0 : fd_boot( argc, argv ); 57 0 : (void) atexit( fd_halt ); 58 0 : fd_log_level_core_set( 3 ); /* crash on warning log */ 59 : 60 0 : FD_TEST( fd_grpc_client_footprint( buf_max )<=sizeof(client_mem)); 61 0 : return 0; 62 0 : } 63 : 64 : int 65 : LLVMFuzzerTestOneInput( uchar const *data, 66 : ulong size ) { 67 : #define PARAMS_SIZE (3) 68 : if( FD_UNLIKELY( size < PARAMS_SIZE )) { 69 : return 1; 70 : } 71 : fd_grpc_client_metrics_t metrics = {0}; 72 : void *app_ctx = (void *) (0x1234UL); 73 : ulong rng_seed = 1UL; 74 : fd_grpc_client_t *client = fd_grpc_client_new( client_mem, &callbacks, &metrics, app_ctx, buf_max, rng_seed ); 75 : FD_TEST( client ); 76 : 77 : fd_grpc_client_reset( client ); 78 : test_grpc_client_mock_conn( client ); 79 : 80 : fd_grpc_h2_stream_t *stream = fd_grpc_client_stream_acquire( client, 0UL ); 81 : FD_TEST( stream ); 82 : FD_TEST( !stream->hdrs_received ); 83 : 84 : /* Inject a few bits of state so that the code paths inside the 85 : callback can be exercised. */ 86 : stream->hdrs.is_grpc_proto = data[ 0 ] & 1u; 87 : stream->hdrs.h2_status = data[ 1 ]; 88 : ulong flags = data[ 2 ]; 89 : 90 : uchar const *payload = data+PARAMS_SIZE; 91 : ulong payload_sz = size>PARAMS_SIZE ? size-PARAMS_SIZE : 0UL; 92 : 93 : fd_grpc_h2_cb_headers( client->conn, &stream->s, payload, payload_sz, flags ); 94 : 95 : /* stream may have been released by the callback, so we ask the 96 : client whether it is still around before touching it again. */ 97 : if( fd_grpc_client_stream_acquire_is_safe( client )) { 98 : /* The stream is still alive. Basic invariants: hdrs_received 99 : is a boolean and msg_buf_used never exceeds its capacity. */ 100 : FD_TEST( stream->hdrs_received<=1 ); 101 : FD_TEST( stream->msg_buf_used<=stream->msg_buf_max ); 102 : } 103 : 104 : fd_grpc_client_delete( client ); 105 : #undef PARAMS_SIZE 106 : return 0; 107 : }