Skip to content

Commit

Permalink
fuzzing: fixing harness input region derivation
Browse files Browse the repository at this point in the history
  • Loading branch information
ibhatt-jumptrading committed Jan 16, 2025
1 parent 543c912 commit e4fe9ae
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 65 deletions.
10 changes: 0 additions & 10 deletions src/flamenco/runtime/tests/fd_dump_pb.c
Original file line number Diff line number Diff line change
Expand Up @@ -605,16 +605,6 @@ fd_dump_vm_cpi_state( fd_vm_t * vm,
sys_ctx.syscall_invocation.heap_prefix->size = (pb_size_t) vm->instr_ctx->txn_ctx->heap_size;
fd_memcpy( sys_ctx.syscall_invocation.heap_prefix->bytes, vm->heap, vm->instr_ctx->txn_ctx->heap_size );

sys_ctx.vm_ctx.input_data_regions_count = vm->input_mem_regions_cnt;
sys_ctx.vm_ctx.input_data_regions = fd_scratch_alloc( 8UL, sizeof(fd_exec_test_input_data_region_t) * vm->input_mem_regions_cnt );
for( ulong i=0UL; i<vm->input_mem_regions_cnt; i++ ) {
sys_ctx.vm_ctx.input_data_regions[i].content = fd_scratch_alloc( 8UL, PB_BYTES_ARRAY_T_ALLOCSIZE(vm->input_mem_regions[i].region_sz) );
sys_ctx.vm_ctx.input_data_regions[i].content->size = (pb_size_t) vm->input_mem_regions[i].region_sz;
fd_memcpy( sys_ctx.vm_ctx.input_data_regions[i].content->bytes, (uchar *) vm->input_mem_regions[i].haddr, vm->input_mem_regions[i].region_sz );
sys_ctx.vm_ctx.input_data_regions[i].offset = vm->input_mem_regions[i].vaddr_offset;
sys_ctx.vm_ctx.input_data_regions[i].is_writable = vm->input_mem_regions[i].is_writable;
}

create_instr_context_protobuf_from_instructions( &sys_ctx.instr_ctx,
vm->instr_ctx->txn_ctx,
vm->instr_ctx->instr );
Expand Down
52 changes: 32 additions & 20 deletions src/flamenco/runtime/tests/fd_exec_instr_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "../fd_account.h"
#include "../fd_executor.h"
#include "../fd_runtime.h"
#include "../program/fd_bpf_loader_serialization.h"
#include "../program/fd_bpf_loader_program.h"
#include "../program/fd_bpf_program_util.h"
#include "../program/fd_builtin_programs.h"
Expand Down Expand Up @@ -1439,17 +1440,6 @@ fd_exec_vm_syscall_test_run( fd_exec_instr_test_runner_t * runner,
fd_memcpy( rodata, input->vm_ctx.rodata->bytes, rodata_sz );
}

/* Load input data regions */
fd_vm_input_region_t * input_regions = NULL;
uint input_regions_count = 0U;
if( !!(input->vm_ctx.input_data_regions_count) ) {
input_regions = fd_spad_alloc_debug( spad, alignof(fd_vm_input_region_t), sizeof(fd_vm_input_region_t) * input->vm_ctx.input_data_regions_count );
input_regions_count = fd_setup_vm_input_regions( input_regions, input->vm_ctx.input_data_regions, input->vm_ctx.input_data_regions_count, spad );
if ( !input_regions_count ) {
goto error;
}
}

if( input->vm_ctx.heap_max > FD_VM_HEAP_MAX ) {
goto error;
}
Expand All @@ -1461,9 +1451,35 @@ fd_exec_vm_syscall_test_run( fd_exec_instr_test_runner_t * runner,

/* If the program ID account owner is the v1 BPF loader, then alignment is disabled (controlled by
the `is_deprecated` flag) */

ulong input_sz = 0UL;
ulong pre_lens[256] = {0};
fd_vm_input_region_t input_mem_regions[1000] = {0}; /* We can have a max of (3 * num accounts + 1) regions */
fd_vm_acc_region_meta_t acc_region_metas[256] = {0}; /* instr acc idx to idx */
uint input_mem_regions_cnt = 0U;
int direct_mapping = FD_FEATURE_ACTIVE( ctx->slot_ctx, bpf_account_data_direct_mapping );

uchar program_id_idx = ctx->instr->program_id;
uchar is_deprecated = ( program_id_idx < ctx->txn_ctx->accounts_cnt ) &&
( !memcmp( ctx->txn_ctx->borrowed_accounts[program_id_idx].const_meta->info.owner, fd_solana_bpf_loader_deprecated_program_id.key, sizeof(fd_pubkey_t) ) );
uchar is_deprecated = (program_id_idx < ctx->txn_ctx->accounts_cnt) &&
(!memcmp( ctx->txn_ctx->borrowed_accounts[program_id_idx].const_meta->info.owner, fd_solana_bpf_loader_deprecated_program_id.key, sizeof(fd_pubkey_t) ));

if( is_deprecated ) {
fd_bpf_loader_input_serialize_unaligned( *ctx,
&input_sz,
pre_lens,
input_mem_regions,
&input_mem_regions_cnt,
acc_region_metas,
!direct_mapping );
} else {
fd_bpf_loader_input_serialize_aligned( *ctx,
&input_sz,
pre_lens,
input_mem_regions,
&input_mem_regions_cnt,
acc_region_metas,
!direct_mapping );
}

fd_vm_init(
vm,
Expand All @@ -1482,9 +1498,9 @@ fd_exec_vm_syscall_test_run( fd_exec_instr_test_runner_t * runner,
syscalls,
NULL, // TODO
sha,
input_regions,
input_regions_count,
NULL,
input_mem_regions,
input_mem_regions_cnt,
acc_region_metas,
is_deprecated,
FD_FEATURE_ACTIVE( ctx->slot_ctx, bpf_account_data_direct_mapping ) );

Expand Down Expand Up @@ -1515,10 +1531,6 @@ fd_exec_vm_syscall_test_run( fd_exec_instr_test_runner_t * runner,
fd_ulong_min(input->syscall_invocation.stack_prefix->size, FD_VM_STACK_MAX) );
}

// Propogate the acc_regions_meta to the vm
vm->acc_region_metas = fd_valloc_malloc( valloc, alignof(fd_vm_acc_region_meta_t), sizeof(fd_vm_acc_region_meta_t) * input->vm_ctx.input_data_regions_count );
fd_setup_vm_acc_region_metas( vm->acc_region_metas, vm, vm->instr_ctx );

// Look up the syscall to execute
char * syscall_name = (char *)input->syscall_invocation.function_name.bytes;
fd_sbpf_syscalls_t const * syscall = lookup_syscall_func(syscalls, syscall_name, input->syscall_invocation.function_name.size);
Expand Down
63 changes: 44 additions & 19 deletions src/flamenco/runtime/tests/fd_vm_test.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#include "fd_vm_test.h"
#include "fd_exec_instr_test.h"
#include "../fd_system_ids.h"
#include "generated/vm.pb.h"
#include "../program/fd_bpf_loader_serialization.h"


int
fd_vm_syscall_noop( void * _vm,
Expand Down Expand Up @@ -94,11 +97,42 @@ do{
uchar * rodata = fd_spad_alloc_debug( spad, 8UL, rodata_sz );
memcpy( rodata, input->vm_ctx.rodata->bytes, rodata_sz );

/* Load input data regions */
fd_vm_input_region_t * input_regions = fd_spad_alloc_debug( spad, alignof(fd_vm_input_region_t), sizeof(fd_vm_input_region_t) * input->vm_ctx.input_data_regions_count );
uint input_regions_cnt = fd_setup_vm_input_regions( input_regions, input->vm_ctx.input_data_regions, input->vm_ctx.input_data_regions_count, spad );
/* Enable direct_mapping for SBPF version >= v1 */
if( input->vm_ctx.sbpf_version >= FD_SBPF_V1 ) {
((fd_exec_epoch_ctx_t *)(instr_ctx->epoch_ctx))->features.bpf_account_data_direct_mapping = 0UL;
}

/* Setup input region */
ulong input_sz = 0UL;
ulong pre_lens[256] = {0};
fd_vm_input_region_t input_mem_regions[1000] = {0}; /* We can have a max of (3 * num accounts + 1) regions */
fd_vm_acc_region_meta_t acc_region_metas[256] = {0}; /* instr acc idx to idx */
uint input_mem_regions_cnt = 0U;
int direct_mapping = FD_FEATURE_ACTIVE( instr_ctx->slot_ctx, bpf_account_data_direct_mapping );

uchar program_id_idx = instr_ctx->instr->program_id;
uchar is_deprecated = (program_id_idx < instr_ctx->txn_ctx->accounts_cnt) &&
(!memcmp( instr_ctx->txn_ctx->borrowed_accounts[program_id_idx].const_meta->info.owner, fd_solana_bpf_loader_deprecated_program_id.key, sizeof(fd_pubkey_t) ));

if( is_deprecated ) {
fd_bpf_loader_input_serialize_unaligned( *instr_ctx,
&input_sz,
pre_lens,
input_mem_regions,
&input_mem_regions_cnt,
acc_region_metas,
!direct_mapping );
} else {
fd_bpf_loader_input_serialize_aligned( *instr_ctx,
&input_sz,
pre_lens,
input_mem_regions,
&input_mem_regions_cnt,
acc_region_metas,
!direct_mapping );
}

if (input->vm_ctx.heap_max > FD_VM_HEAP_DEFAULT) {
if( input->vm_ctx.heap_max>FD_VM_HEAP_DEFAULT ) {
break;
}

Expand Down Expand Up @@ -147,11 +181,6 @@ do{
fd_vm_t * vm = fd_vm_join( fd_vm_new( fd_valloc_malloc( valloc, fd_vm_align(), fd_vm_footprint() ) ) );
FD_TEST( vm );

/* Enable direct_mapping for SBPF version >= v1 */
if( input->vm_ctx.sbpf_version >= FD_SBPF_V1 ) {
((fd_exec_epoch_ctx_t *)(instr_ctx->epoch_ctx))->features.bpf_account_data_direct_mapping = 0UL;
}

fd_vm_init(
vm,
instr_ctx,
Expand All @@ -169,11 +198,11 @@ do{
syscalls,
trace, /* trace */
NULL, /* sha */
input_regions,
input_regions_cnt,
NULL, /* vm_acc_region_meta*/
0, /* is deprecated */
FD_FEATURE_ACTIVE( instr_ctx->slot_ctx, bpf_account_data_direct_mapping ) /* direct mapping */
input_mem_regions,
input_mem_regions_cnt,
acc_region_metas, /* vm_acc_region_meta*/
is_deprecated, /* is deprecated */
direct_mapping /* direct mapping */
);

/* Setup registers.
Expand All @@ -196,12 +225,8 @@ do{
// vm->reg[10] = input->vm_ctx.r10; // do not override
// vm->reg[11] = input->vm_ctx.r11; // do not override

// Propagate the acc_regions_meta to the vm
vm->acc_region_metas = fd_valloc_malloc( valloc, alignof(fd_vm_acc_region_meta_t), sizeof(fd_vm_acc_region_meta_t) * input->vm_ctx.input_data_regions_count );
fd_setup_vm_acc_region_metas( vm->acc_region_metas, vm, vm->instr_ctx );

// Validate the vm
if ( fd_vm_validate( vm ) != FD_VM_SUCCESS ) {
if( fd_vm_validate( vm ) != FD_VM_SUCCESS ) {
// custom error, avoid -1 because we use it for "unknown error" in solfuzz-agave
effects->error = -2;
break;
Expand Down
2 changes: 1 addition & 1 deletion src/flamenco/runtime/tests/fetch_and_generate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ fi

# Fetch protosol
if [ ! -d protosol ]; then
git clone --depth=1 -q https://github.com/firedancer-io/protosol.git
git clone -q https://github.com/firedancer-io/protosol.git
else
cd protosol
git pull -q
Expand Down
10 changes: 2 additions & 8 deletions src/flamenco/runtime/tests/generated/vm.pb.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 8 additions & 7 deletions src/flamenco/vm/syscall/fd_vm_syscall_cpi_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -707,13 +707,6 @@ VM_SYSCALL_CPI_ENTRYPOINT( void * _vm,
FD_VM_ALIGN_RUST_U8,
VM_SYSCALL_CPI_INSTR_DATA_LEN( cpi_instruction ));

/* Authorized program check *************************************************/

if( FD_UNLIKELY( fd_vm_syscall_cpi_check_authorized_program( program_id, vm->instr_ctx->slot_ctx, data, VM_SYSCALL_CPI_INSTR_DATA_LEN( cpi_instruction ) ) ) ) {
/* https://github.com/solana-labs/solana/blob/2afde1b028ed4593da5b6c735729d8994c4bfac6/programs/bpf_loader/src/syscalls/cpi.rs#L1054 */
FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_PROGRAM_NOT_SUPPORTED );
return FD_VM_SYSCALL_ERR_PROGRAM_NOT_SUPPORTED;
}

/* Instruction checks ***********************************************/

Expand Down Expand Up @@ -746,6 +739,14 @@ VM_SYSCALL_CPI_ENTRYPOINT( void * _vm,
return err;
}

/* Authorized program check *************************************************/

if( FD_UNLIKELY( fd_vm_syscall_cpi_check_authorized_program( program_id, vm->instr_ctx->slot_ctx, data, VM_SYSCALL_CPI_INSTR_DATA_LEN( cpi_instruction ) ) ) ) {
/* https://github.com/solana-labs/solana/blob/2afde1b028ed4593da5b6c735729d8994c4bfac6/programs/bpf_loader/src/syscalls/cpi.rs#L1054 */
FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_PROGRAM_NOT_SUPPORTED );
return FD_VM_SYSCALL_ERR_PROGRAM_NOT_SUPPORTED;
}

/* Translate account infos ******************************************/
/* Direct mapping check
https://github.com/anza-xyz/agave/blob/v2.1.0/programs/bpf_loader/src/syscalls/cpi.rs#L805-L814 */
Expand Down

0 comments on commit e4fe9ae

Please sign in to comment.