Line data Source code
1 : #include "fd_elf_harness.h" 2 : 3 : ulong 4 : fd_runtime_fuzz_sbpf_load_run( fd_runtime_fuzz_runner_t * runner, 5 : void const * input_, 6 : void ** output_, 7 : void * output_buf, 8 0 : ulong output_bufsz ) { 9 0 : fd_exec_test_elf_loader_ctx_t const * input = fd_type_pun_const( input_ ); 10 0 : fd_exec_test_elf_loader_effects_t ** output = fd_type_pun( output_ ); 11 : 12 0 : fd_sbpf_elf_info_t info; 13 0 : fd_valloc_t valloc = fd_spad_virtual( runner->spad ); 14 : 15 0 : if ( FD_UNLIKELY( !input->has_elf || !input->elf.data ) ){ 16 0 : return 0UL; 17 0 : } 18 : 19 0 : void const * elf_bin = input->elf.data->bytes; 20 0 : ulong elf_sz = input->elf.data->size; 21 : 22 : // Allocate space for captured effects 23 0 : ulong output_end = (ulong)output_buf + output_bufsz; 24 0 : FD_SCRATCH_ALLOC_INIT( l, output_buf ); 25 : 26 0 : fd_exec_test_elf_loader_effects_t * elf_effects = 27 0 : FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_exec_test_elf_loader_effects_t), 28 0 : sizeof (fd_exec_test_elf_loader_effects_t) ); 29 0 : if( FD_UNLIKELY( _l > output_end ) ) { 30 : /* return 0 on fuzz-specific failures */ 31 0 : return 0UL; 32 0 : } 33 0 : fd_memset( elf_effects, 0, sizeof(fd_exec_test_elf_loader_effects_t) ); 34 : 35 : /* wrap the loader code in do-while(0) block so that we can exit 36 : immediately if execution fails at any point */ 37 : 38 0 : do{ 39 : 40 0 : if( FD_UNLIKELY( !fd_sbpf_elf_peek( &info, elf_bin, elf_sz, input->deploy_checks, FD_SBPF_V0, FD_SBPF_V3 ) ) ) { 41 : /* return incomplete effects on execution failures */ 42 0 : break; 43 0 : } 44 : 45 0 : void* rodata = fd_valloc_malloc( valloc, FD_SBPF_PROG_RODATA_ALIGN, info.rodata_footprint ); 46 0 : FD_TEST( rodata ); 47 : 48 0 : fd_sbpf_program_t * prog = fd_sbpf_program_new( fd_valloc_malloc( valloc, fd_sbpf_program_align(), fd_sbpf_program_footprint( &info ) ), &info, rodata ); 49 0 : FD_TEST( prog ); 50 : 51 0 : fd_sbpf_syscalls_t * syscalls = fd_sbpf_syscalls_new( fd_valloc_malloc( valloc, fd_sbpf_syscalls_align(), fd_sbpf_syscalls_footprint() )); 52 0 : FD_TEST( syscalls ); 53 : 54 0 : fd_vm_syscall_register_all( syscalls, 0 ); 55 : 56 0 : int res = fd_sbpf_program_load( prog, elf_bin, elf_sz, syscalls, input->deploy_checks ); 57 0 : if( FD_UNLIKELY( res ) ) { 58 0 : break; 59 0 : } 60 : 61 0 : fd_memset( elf_effects, 0, sizeof(fd_exec_test_elf_loader_effects_t) ); 62 0 : elf_effects->rodata_sz = prog->rodata_sz; 63 : 64 : // Load rodata section 65 0 : elf_effects->rodata = FD_SCRATCH_ALLOC_APPEND(l, 8UL, PB_BYTES_ARRAY_T_ALLOCSIZE( prog->rodata_sz )); 66 0 : if( FD_UNLIKELY( _l > output_end ) ) { 67 0 : return 0UL; 68 0 : } 69 0 : elf_effects->rodata->size = (pb_size_t) prog->rodata_sz; 70 0 : fd_memcpy( elf_effects->rodata->bytes, prog->rodata, prog->rodata_sz ); 71 : 72 0 : elf_effects->text_cnt = prog->text_cnt; 73 0 : elf_effects->text_off = prog->text_off; 74 0 : elf_effects->entry_pc = prog->entry_pc; 75 : 76 : 77 0 : pb_size_t calldests_sz = (pb_size_t) fd_sbpf_calldests_cnt( prog->calldests); 78 0 : elf_effects->calldests_count = calldests_sz; 79 0 : elf_effects->calldests = FD_SCRATCH_ALLOC_APPEND(l, 8UL, calldests_sz * sizeof(uint64_t)); 80 0 : if( FD_UNLIKELY( _l > output_end ) ) { 81 0 : return 0UL; 82 0 : } 83 : 84 0 : ulong i = 0; 85 0 : for(ulong target_pc = fd_sbpf_calldests_const_iter_init(prog->calldests); !fd_sbpf_calldests_const_iter_done(target_pc); 86 0 : target_pc = fd_sbpf_calldests_const_iter_next(prog->calldests, target_pc)) { 87 0 : elf_effects->calldests[i] = target_pc; 88 0 : ++i; 89 0 : } 90 0 : } while(0); 91 : 92 0 : ulong actual_end = FD_SCRATCH_ALLOC_FINI( l, 1UL ); 93 : 94 0 : *output = elf_effects; 95 0 : return actual_end - (ulong) output_buf; 96 0 : }