LCOV - code coverage report
Current view: top level - flamenco/runtime - fuzz_genesis_parse.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 7 37 18.9 %
Date: 2026-01-09 05:14:11 Functions: 1 2 50.0 %

          Line data    Source code
       1             : #include "fd_genesis_parse.h"
       2             : #include "fd_runtime_const.h"
       3             : #include <assert.h>
       4             : #include <stdlib.h>
       5             : 
       6             : static uchar genesis_buf[ FD_GENESIS_MAX_MESSAGE_SIZE ] __attribute__((aligned(alignof(fd_genesis_t))));
       7             : 
       8             : int
       9             : LLVMFuzzerInitialize( int  *   argc,
      10          12 :                       char *** argv ) {
      11             :   /* Set up shell without signal handlers */
      12          12 :   putenv( "FD_LOG_BACKTRACE=0" );
      13          12 :   fd_boot( argc, argv );
      14          12 :   fd_log_level_stderr_set(4);
      15          12 :   atexit( fd_halt );
      16          12 :   return 0;
      17          12 : }
      18             : 
      19             : static int
      20           0 : genesis_accounts_check( uchar genesis_buf[ static FD_GENESIS_MAX_MESSAGE_SIZE ] ) {
      21             : 
      22           0 :   fd_genesis_t * genesis                = fd_type_pun( genesis_buf );
      23           0 :   ulong          genesis_sz             = genesis->total_sz;
      24           0 :   ulong          lowest_expected_offset = sizeof(fd_genesis_t);
      25             : 
      26           0 :   if( FD_UNLIKELY( genesis_sz>FD_GENESIS_MAX_MESSAGE_SIZE ) ) return 0;
      27             : 
      28           0 :   if( FD_UNLIKELY( genesis->accounts_len>FD_GENESIS_ACCOUNT_MAX_COUNT ) ) return 0;
      29           0 :   for( ulong i=0UL; i<genesis->accounts_len; i++ ) {
      30           0 :     ulong account_off = genesis->accounts_off[ i ];
      31           0 :     if( FD_UNLIKELY( account_off>genesis_sz ) )             return 0;
      32           0 :     if( FD_UNLIKELY( account_off<lowest_expected_offset ) ) return 0;
      33             : 
      34           0 :     fd_genesis_account_t * account = fd_type_pun( genesis_buf+account_off );
      35           0 :     if( FD_UNLIKELY( account->meta.dlen>FD_RUNTIME_ACC_SZ_MAX ) ) return 0;
      36             : 
      37           0 :     ulong next_offset = account_off+sizeof(fd_genesis_account_t)+account->meta.dlen;
      38           0 :     if( FD_UNLIKELY( next_offset<lowest_expected_offset ) ) return 0;
      39           0 :     lowest_expected_offset = next_offset;
      40           0 :   }
      41             : 
      42           0 :   if( FD_UNLIKELY( genesis->builtin_len>FD_GENESIS_BUILTIN_MAX_COUNT ) ) return 0;
      43           0 :   for( ulong i=0UL; i<genesis->builtin_len; i++ ) {
      44           0 :     ulong builtin_off = genesis->builtin_off[ i ];
      45           0 :     if( FD_UNLIKELY( builtin_off>genesis_sz ) )             return 0;
      46           0 :     if( FD_UNLIKELY( builtin_off<lowest_expected_offset ) ) return 0;
      47             : 
      48           0 :     fd_genesis_builtin_t * builtin = fd_type_pun( genesis_buf+builtin_off );
      49           0 :     if( FD_UNLIKELY( builtin->data_len>FD_RUNTIME_ACC_SZ_MAX ) ) return 0;
      50             : 
      51           0 :     ulong next_offset = builtin_off+sizeof(fd_genesis_builtin_t)+builtin->data_len;
      52           0 :     if( FD_UNLIKELY( next_offset<lowest_expected_offset ) ) return 0;
      53           0 :     lowest_expected_offset = next_offset;
      54           0 :   }
      55             : 
      56           0 :   if( FD_UNLIKELY( lowest_expected_offset>genesis_sz  ) ) return 0;
      57           0 :   return 1;
      58           0 : }
      59             : 
      60             : int
      61             : LLVMFuzzerTestOneInput( uchar const * data,
      62             :                         ulong         size ) {
      63             : 
      64             :   if( !fd_genesis_parse( genesis_buf, data, size ) ) return 0;
      65             :   /* In the genesis, the only two fields that are not fixed size are the
      66             :      accounts and the built-in accounts.  The offsets and bounds of each
      67             :      of the accounts are checked here. */
      68             :   assert( genesis_accounts_check( genesis_buf ) );
      69             : 
      70             :   return 0;
      71             : }

Generated by: LCOV version 1.14