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