LCOV - code coverage report
Current view: top level - waltz/quic/tests - fuzz_quic.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 105 121 86.8 %
Date: 2025-01-08 12:08:44 Functions: 5 6 83.3 %

          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             : #include <unistd.h>
       9             : 
      10             : #include "../../../util/sanitize/fd_fuzz.h"
      11             : 
      12             : #pragma GCC diagnostic ignored "-Wunused-function"
      13             : #include "../fd_quic.h"
      14             : #include "../fd_quic_private.h"
      15             : #include "../fd_quic_proto.h"
      16             : 
      17             : #include "fd_quic_test_helpers.h"
      18             : 
      19             : fd_quic_t *server_quic = NULL;
      20             : 
      21             : uchar scratch[0x4000];
      22             : size_t scratch_sz = 0x4000;
      23             : 
      24             : fd_aio_t _aio[1];
      25             : 
      26             : int test_aio_send_func(void *ctx, fd_aio_pkt_info_t const *batch,
      27          33 :                        ulong batch_cnt, ulong *opt_batch_idx, int flush) {
      28          33 :   (void)flush;
      29          33 :   (void)batch;
      30          33 :   (void)batch_cnt;
      31          33 :   (void)opt_batch_idx;
      32          33 :   (void)ctx;
      33          33 :   return 0;
      34          33 : }
      35             : 
      36       38580 : uint send_packet(uchar const *payload, size_t payload_sz) {
      37             : 
      38       38580 :   if (FD_UNLIKELY(payload_sz <= 0L)) {
      39       21660 :     return 0u;
      40       21660 :   }
      41             : 
      42       16920 :   uchar *cur_ptr = scratch;
      43       16920 :   ulong cur_sz = scratch_sz;
      44             : 
      45       16920 :   fd_quic_pkt_t pkt;
      46             : 
      47       16920 :   pkt.ip4->verihl = FD_IP4_VERIHL(4,5);
      48       16920 :   pkt.ip4->tos = 0;
      49       16920 :   pkt.ip4->net_tot_len = (ushort)(20 + 8 + payload_sz);
      50       16920 :   pkt.ip4->net_id = 0;
      51       16920 :   pkt.ip4->net_frag_off = 0x4000u;
      52       16920 :   pkt.ip4->ttl = 64; /* TODO make configurable */
      53       16920 :   pkt.ip4->protocol = FD_IP4_HDR_PROTOCOL_UDP;
      54       16920 :   pkt.ip4->check = 0;
      55             : 
      56       16920 :   pkt.udp->net_sport = 0x2;
      57       16920 :   pkt.udp->net_dport = 0x1;
      58       16920 :   pkt.udp->net_len = (ushort)(8 + payload_sz);
      59       16920 :   pkt.udp->check = 0x0000;
      60             : 
      61       16920 :   ulong rc = fd_quic_encode_ip4(cur_ptr, cur_sz, pkt.ip4);
      62       16920 :   if (FD_UNLIKELY(rc == FD_QUIC_PARSE_FAIL)) {
      63           0 :     return 1;
      64           0 :   }
      65             : 
      66             :   /* Compute checksum over network byte order header */
      67       16920 :   fd_ip4_hdr_t *ip4_encoded = (fd_ip4_hdr_t *)fd_type_pun(cur_ptr);
      68       16920 :   ip4_encoded->check = (ushort)fd_ip4_hdr_check_fast(ip4_encoded);
      69             : 
      70       16920 :   cur_ptr += rc;
      71       16920 :   cur_sz -= rc;
      72             : 
      73       16920 :   rc = fd_quic_encode_udp(cur_ptr, cur_sz, pkt.udp);
      74       16920 :   if (FD_UNLIKELY(rc == FD_QUIC_PARSE_FAIL)) {
      75           0 :     return 1;
      76           0 :   }
      77             : 
      78       16920 :   cur_ptr += rc;
      79       16920 :   cur_sz -= rc;
      80             : 
      81       16920 :   if (FD_UNLIKELY((ulong)payload_sz > cur_sz)) {
      82           0 :     return FD_QUIC_FAILED;
      83           0 :   }
      84       16920 :   fd_memcpy(cur_ptr, payload, (ulong)payload_sz);
      85             : 
      86       16920 :   cur_ptr += (ulong)payload_sz;
      87       16920 :   cur_sz -= (ulong)payload_sz;
      88             : 
      89       16920 :   fd_quic_process_packet( server_quic, scratch, scratch_sz - cur_sz );
      90             : 
      91       16920 :   return FD_QUIC_SUCCESS; /* success */
      92       16920 : }
      93             : 
      94        1200 : void init_quic(void) {
      95        1200 :   void *ctx = (void *)0x1234UL;
      96        1200 :   void *shaio = fd_aio_new(_aio, ctx, test_aio_send_func);
      97        1200 :   assert( shaio );
      98           0 :   fd_aio_t *aio = fd_aio_join(shaio);
      99        1200 :   assert(aio);
     100             : 
     101           0 :   fd_quic_set_aio_net_tx(server_quic, aio);
     102        1200 :   fd_quic_init( server_quic );
     103        1200 : }
     104             : 
     105             : void
     106           0 : destroy_quic( void ) {
     107           0 :   fd_quic_fini( server_quic );
     108           0 : }
     109             : 
     110           3 : int LLVMFuzzerInitialize(int *argc, char ***argv) {
     111             :   /* Set up shell without signal handlers */
     112           3 :   putenv("FD_LOG_BACKTRACE=0");
     113           3 :   fd_boot(argc, argv);
     114           3 : # ifndef FD_DEBUG_MODE
     115           3 :   fd_log_level_core_set(3); /* crash on warning log */
     116           3 : # endif
     117           3 :   atexit(fd_halt);
     118             : 
     119             :   /* Use unoptimized wksp memory */
     120             : 
     121           3 :   ulong wksp_sz = 13107200UL * 2;
     122             : 
     123           3 :   uchar * mem = aligned_alloc( 4096UL, wksp_sz );
     124           3 :   assert( mem );
     125             : 
     126           0 :   ulong part_max = fd_wksp_part_max_est( wksp_sz, 64UL<<10 );
     127           3 :   assert( part_max );
     128           0 :   ulong data_max = fd_wksp_data_max_est( wksp_sz, 64UL<<10 );
     129             : 
     130           3 :   fd_wksp_t * wksp = fd_wksp_join( fd_wksp_new( mem, "wksp", 42U, part_max, data_max ) );
     131           3 :   assert( wksp );
     132             : 
     133           3 :   int shmem_err = fd_shmem_join_anonymous( "wksp", FD_SHMEM_JOIN_MODE_READ_WRITE, wksp, mem, 4096UL, wksp_sz/4096UL );
     134           3 :   assert( !shmem_err );
     135             : 
     136           0 :   fd_quic_limits_t const quic_limits = {.conn_cnt = 10,
     137           3 :                                         .conn_id_cnt = 10,
     138           3 :                                         .handshake_cnt = 10,
     139           3 :                                         .stream_pool_cnt = 640,
     140           3 :                                         .inflight_pkt_cnt = 1024,
     141           3 :                                         .tx_buf_sz = 1 << 14};
     142             : 
     143           3 :   ulong quic_footprint = fd_quic_footprint(&quic_limits);
     144           3 :   assert( quic_footprint );
     145             : 
     146           0 :   fd_rng_t _rng[1]; fd_rng_t * rng = fd_rng_join( fd_rng_new( _rng, 0U, 0UL ) );
     147           3 :   server_quic = fd_quic_new_anonymous(wksp, &quic_limits, FD_QUIC_ROLE_SERVER, rng);
     148           3 :   assert( server_quic );
     149           0 :   fd_rng_delete( fd_rng_leave( rng ) );
     150             : 
     151           3 :   fd_quic_config_t *server_config = &server_quic->config;
     152           3 :   server_config->idle_timeout = 5e6;
     153           3 :   server_config->retry = 1;
     154             : 
     155           3 :   server_quic->config.initial_rx_max_stream_data = 1 << 14;
     156             :   // server_quic->config.retry = 1;
     157             : 
     158           3 :   return 0;
     159           3 : }
     160             : 
     161        1200 : int LLVMFuzzerTestOneInput(uchar const *data, ulong size) {
     162        1200 :   ulong s = size;
     163        1200 :   uchar const *ptr = data;
     164             : 
     165        1200 :   init_quic();
     166             : 
     167       39780 :   while (s > 2) {
     168       39360 :     FD_FUZZ_MUST_BE_COVERED;
     169       39360 :     ushort payload_sz = (ushort)( ptr[0] + ( ptr[1] << 8u ) );
     170       39360 :     ptr += 2;
     171       39360 :     s -= 2;
     172       39360 :     if (payload_sz <= s) {
     173       38580 :       send_packet(ptr, payload_sz);
     174       38580 :       FD_FUZZ_MUST_BE_COVERED;
     175       38580 :       ptr += payload_sz;
     176       38580 :       s -= payload_sz;
     177       38580 :     } else {
     178         780 :       FD_FUZZ_MUST_BE_COVERED;
     179         780 :       fd_quic_fini(server_quic);
     180         780 :       return 0;
     181         780 :     }
     182       39360 :   }
     183             : 
     184         420 :   fd_quic_fini(server_quic);
     185             : 
     186         420 :   FD_FUZZ_MUST_BE_COVERED;
     187         420 :   return 0;
     188        1200 : }

Generated by: LCOV version 1.14