Skip to content

Commit

Permalink
flamenco, fuzz: CPI fuzzing
Browse files Browse the repository at this point in the history
  • Loading branch information
ravyu-jump committed Jul 30, 2024
1 parent 3eb183a commit 26169ce
Show file tree
Hide file tree
Showing 12 changed files with 497 additions and 23 deletions.
9 changes: 8 additions & 1 deletion .github/workflows/clusterfuzz.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,16 @@ jobs:
ls ${{ env.OBJ_DIR }}/fuzz-test
ls ${{ env.OBJ_DIR }}/lib
- name: upload lib artifact
- name: upload so artifact
uses: actions/upload-artifact@v4
with:
path: ${{ env.OBJ_DIR }}/lib/libfd_exec_sol_compat.so
name: libfd_exec_sol_compat
retention-days: 14

- name: upload stubbed so artifact
uses: actions/upload-artifact@v4
with:
path: ${{ env.OBJ_DIR }}/lib/libfd_exec_sol_compat_stubbed.so
name: libfd_exec_sol_compat_stubbed
retention-days: 14
8 changes: 4 additions & 4 deletions src/flamenco/runtime/fd_executor.c
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ dump_sorted_features( const fd_features_t * features, fd_exec_test_feature_set_t
}

static void
dump_account_state( fd_borrowed_account_t * borrowed_account,
dump_account_state( fd_borrowed_account_t const * borrowed_account,
fd_exec_test_acct_state_t * output_account ) {
// Address
fd_memcpy(output_account->address, borrowed_account->pubkey, sizeof(fd_pubkey_t));
Expand Down Expand Up @@ -512,8 +512,8 @@ dump_account_state( fd_borrowed_account_t * borrowed_account,

static void
create_instr_context_protobuf_from_instructions( fd_exec_test_instr_context_t * instr_context,
fd_exec_txn_ctx_t *txn_ctx,
fd_instr_info_t *instr ) {
fd_exec_txn_ctx_t const *txn_ctx,
fd_instr_info_t const *instr ) {
/*
NOTE: Calling this function requires the caller to have a scratch frame ready (see dump_instr_to_protobuf)
*/
Expand Down Expand Up @@ -541,7 +541,7 @@ create_instr_context_protobuf_from_instructions( fd_exec_test_instr_context_t *
instr_context->accounts = fd_scratch_alloc(alignof(fd_exec_test_acct_state_t), (instr_context->accounts_count + num_sysvar_entries + txn_ctx->executable_cnt) * sizeof(fd_exec_test_acct_state_t));
for( ulong i = 0; i < txn_ctx->accounts_cnt; i++ ) {
// Copy account information over
fd_borrowed_account_t * borrowed_account = &txn_ctx->borrowed_accounts[i];
fd_borrowed_account_t const * borrowed_account = &txn_ctx->borrowed_accounts[i];
fd_exec_test_acct_state_t * output_account = &instr_context->accounts[i];
dump_account_state( borrowed_account, output_account );
}
Expand Down
5 changes: 5 additions & 0 deletions src/flamenco/runtime/fd_executor.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@

FD_PROTOTYPES_BEGIN

void
fd_create_instr_context_protobuf_from_instructions( fd_exec_test_instr_context_t * instr_context,
fd_exec_txn_ctx_t const *txn_ctx,
fd_instr_info_t const *instr );

/* fd_exec_instr_fn_t processes an instruction. Returns an error code
in FD_EXECUTOR_INSTR_{ERR_{...},SUCCESS}. */

Expand Down
6 changes: 4 additions & 2 deletions src/flamenco/runtime/tests/Local.mk
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
$(call add-hdrs,generated/context.pb.h,generated/elf.pb.h,generated/invoke.pb.h,generated/txn.pb.h,generated/vm.pb.h)
$(call add-objs,generated/context.pb generated/elf.pb generated/invoke.pb generated/txn.pb generated/vm.pb,fd_flamenco)
$(call add-hdrs,generated/context.pb.h,generated/elf.pb.h,generated/invoke.pb.h,generated/txn.pb.h,generated/vm.pb.h,generated/vm_cpi.pb.h)
$(call add-objs,generated/context.pb generated/elf.pb generated/invoke.pb generated/txn.pb generated/vm.pb generated/vm_cpi.pb,fd_flamenco)

WRAP_FLAGS += -Xlinker --wrap=fd_execute_instr
ifdef FD_HAS_INT128
ifdef FD_HAS_SECP256K1
$(call add-hdrs,fd_exec_instr_test.h fd_vm_validate_test.h)
Expand All @@ -10,6 +11,7 @@ $(call add-objs,fd_exec_sol_compat,fd_flamenco)
$(call make-unit-test,test_exec_instr,test_exec_instr,fd_flamenco fd_funk fd_ballet fd_util fd_disco,$(SECP256K1_LIBS))
$(call make-unit-test,test_exec_sol_compat,test_exec_sol_compat,fd_flamenco fd_funk fd_ballet fd_util fd_disco,$(SECP256K1_LIBS))
$(call make-shared,libfd_exec_sol_compat.so,fd_exec_sol_compat,fd_flamenco fd_funk fd_ballet fd_util fd_disco,$(SECP256K1_LIBS))
$(call make-shared,libfd_exec_sol_compat_stubbed.so,fd_exec_sol_compat,fd_flamenco fd_funk fd_ballet fd_util fd_disco,$(SECP256K1_LIBS) $(WRAP_FLAGS))
endif
endif

Expand Down
25 changes: 23 additions & 2 deletions src/flamenco/runtime/tests/fd_exec_instr_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
#include "../sysvar/fd_sysvar_cache.h"
#include "../sysvar/fd_sysvar_epoch_schedule.h"
#include "../sysvar/fd_sysvar_clock.h"
#include "../../vm/syscall/fd_vm_syscall.h"
#include "../../nanopb/pb_decode.h"
#include "../../nanopb/pb_encode.h"

#pragma GCC diagnostic ignored "-Wformat-extra-args"

Expand Down Expand Up @@ -242,7 +245,7 @@ _instr_context_create( fd_exec_instr_test_runner_t * runner,

/* Initial variables */
txn_ctx->loaded_accounts_data_size_limit = FD_VM_LOADED_ACCOUNTS_DATA_SIZE_LIMIT;
txn_ctx->heap_size = FD_VM_HEAP_SIZE;
txn_ctx->heap_size = fd_ulong_max( txn_ctx->heap_size, FD_VM_HEAP_SIZE ); /* FIXME: bound this to FD_VM_HEAP_MAX?*/

/* Set up epoch context */
fd_epoch_bank_t * epoch_bank = fd_exec_epoch_ctx_epoch_bank( epoch_ctx );
Expand Down Expand Up @@ -517,6 +520,9 @@ _instr_context_create( fd_exec_instr_test_runner_t * runner,
}
info->acct_cnt = (uchar)test_ctx->instr_accounts_count;

// FIXME: Specifically for CPI syscalls, flag guard this?
fd_instr_info_sum_account_lamports( info, &info->starting_lamports_h, &info->starting_lamports_l );

/* This function is used to create context both for instructions and for syscalls,
however some of the remaining checks are only relevant for program instructions. */
if( !is_syscall ) {
Expand Down Expand Up @@ -1625,7 +1631,10 @@ fd_exec_vm_syscall_test_run( fd_exec_instr_test_runner_t * runner,
/* Create execution context */
const fd_exec_test_instr_context_t * input_instr_ctx = &input->instr_ctx;
fd_exec_instr_ctx_t ctx[1];
if( !_instr_context_create( runner, ctx, input_instr_ctx, alloc, true ) )
// Skip extra checks for non-CPI syscalls
bool skip_extra_checks = strncmp( (const char *)input->syscall_invocation.function_name.bytes, "sol_invoke_signed", 17 );

if( !_instr_context_create( runner, ctx, input_instr_ctx, alloc, skip_extra_checks ) )
goto error;
fd_valloc_t valloc = fd_scratch_virtual();

Expand Down Expand Up @@ -1793,3 +1802,15 @@ fd_exec_vm_syscall_test_run( fd_exec_instr_test_runner_t * runner,
_instr_context_destroy( runner, ctx, wksp, alloc );
return 0;
}

/* Stubs fd_execute_instr for binaries compiled with
`-Xlinker --wrap=fd_execute_instr` */
int
__wrap_fd_execute_instr( fd_exec_txn_ctx_t * txn_ctx,
fd_instr_info_t * instr_info )
{
(void)(txn_ctx);
(void)(instr_info);
FD_LOG_WARNING(( "fd_execute_instr is disabled" ));
return FD_EXECUTOR_INSTR_SUCCESS;
}
1 change: 1 addition & 0 deletions src/flamenco/runtime/tests/fd_exec_instr_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "generated/invoke.pb.h"
#include "generated/txn.pb.h"
#include "generated/vm.pb.h"
#include "generated/vm_cpi.pb.h"
#include "../../../funk/fd_funk.h"
#include "../../vm/fd_vm.h"
#include "../../../ballet/murmur3/fd_murmur3.h"
Expand Down
30 changes: 25 additions & 5 deletions src/flamenco/runtime/tests/fd_exec_sol_compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ typedef struct {
ulong supported_feature_cnt;
} sol_compat_features_t;

typedef struct {
uint16_t validator_type;
} sol_compat_metadata_t;

static sol_compat_metadata_t metadata = { .validator_type = 1 /* Firedancer */ };
static sol_compat_features_t features;
static ulong cleaned_up_features[] =
{ 0xd924059c5749c4c1, // secp256k1_program_enabled
Expand Down Expand Up @@ -107,6 +112,16 @@ sol_compat_check_wksp_usage( void ) {
}
}

sol_compat_features_t const *
sol_compat_get_features_v1( void ) {
return &features;
}

sol_compat_metadata_t const *
sol_compat_get_metadata_v1( void ) {
return &metadata;
}

fd_exec_instr_test_runner_t *
sol_compat_setup_scratch_and_runner( void * fmem ) {
// Setup scratch
Expand Down Expand Up @@ -500,10 +515,6 @@ sol_compat_elf_loader_v1( uchar * out,
return ok;
}

sol_compat_features_t const *
sol_compat_get_features_v1( void ) {
return &features;
}

int
sol_compat_vm_syscall_execute_v1( uchar * out,
Expand Down Expand Up @@ -546,7 +557,7 @@ int
sol_compat_vm_validate_v1( uchar * out,
ulong * out_sz,
uchar const * in,
ulong in_sz) {
ulong in_sz ) {
// Setup
ulong fmem[ 64 ];
fd_exec_instr_test_runner_t * runner = sol_compat_setup_scratch_and_runner( fmem );
Expand Down Expand Up @@ -578,3 +589,12 @@ sol_compat_vm_validate_v1( uchar * out,

return ok;
}

int
sol_compat_vm_cpi_syscall_v1( uchar * out,
ulong * out_sz,
uchar const * in,
ulong in_sz ) {
/* Just a wrapper to vm_syscall_execute_v1 */
return sol_compat_vm_syscall_execute_v1( out, out_sz, in, in_sz );
}
11 changes: 8 additions & 3 deletions src/flamenco/runtime/tests/generated/invoke.pb.h

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

28 changes: 28 additions & 0 deletions src/flamenco/runtime/tests/generated/vm_cpi.pb.c

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

Loading

0 comments on commit 26169ce

Please sign in to comment.