diff --git a/src/flamenco/runtime/tests/fd_exec_instr_test.c b/src/flamenco/runtime/tests/fd_exec_instr_test.c index 20c3041636..a84eca1522 100644 --- a/src/flamenco/runtime/tests/fd_exec_instr_test.c +++ b/src/flamenco/runtime/tests/fd_exec_instr_test.c @@ -899,8 +899,28 @@ fd_sbpf_program_load_test_run( fd_exec_test_elf_loader_ctx_t const * input, return 0UL; } - ulong elf_sz = input->elf.data->size; - void const * _bin = input->elf.data->bytes; + ulong elf_sz = input->elf_sz; + void const * _bin; + + /* elf_sz will be passed as arguments to elf loader functions. + pb decoder allocates memory for elf.data based on its actual size, + not elf_sz !. + If elf_sz is larger than the size of actual elf data, this may result + in out-of-bounds accesses which will upset ASAN (however intentional). + So in this case we just copy the data into a memory region of elf_sz bytes + + ! The decoupling of elf_sz and the actual binary size is intentional to test + underflow/overflow behavior */ + if ( elf_sz > input->elf.data->size ){ + void * tmp = fd_valloc_malloc( valloc, 1UL, elf_sz ); + if ( FD_UNLIKELY( !tmp ) ){ + return 0UL; + } + fd_memcpy( tmp, input->elf.data->bytes, input->elf.data->size ); + _bin = tmp; + } else { + _bin = input->elf.data->bytes; + } // Allocate space for captured effects ulong output_end = (ulong)output_buf + output_bufsz; diff --git a/src/flamenco/runtime/tests/fd_exec_test.pb.h b/src/flamenco/runtime/tests/fd_exec_test.pb.h index c309a6c4e6..cce3f4c4ef 100644 --- a/src/flamenco/runtime/tests/fd_exec_test.pb.h +++ b/src/flamenco/runtime/tests/fd_exec_test.pb.h @@ -130,6 +130,7 @@ typedef struct fd_exec_test_elf_loader_ctx { fd_exec_test_elf_binary_t elf; bool has_features; fd_exec_test_feature_set_t features; + uint64_t elf_sz; } fd_exec_test_elf_loader_ctx_t; /* Captures the results of a elf binary load. @@ -169,7 +170,7 @@ extern "C" { #define FD_EXEC_TEST_INSTR_EFFECTS_INIT_DEFAULT {0, false, 0, 0, NULL, 0, NULL} #define FD_EXEC_TEST_INSTR_FIXTURE_INIT_DEFAULT {false, FD_EXEC_TEST_INSTR_CONTEXT_INIT_DEFAULT, false, FD_EXEC_TEST_INSTR_EFFECTS_INIT_DEFAULT} #define FD_EXEC_TEST_ELF_BINARY_INIT_DEFAULT {NULL} -#define FD_EXEC_TEST_ELF_LOADER_CTX_INIT_DEFAULT {false, FD_EXEC_TEST_ELF_BINARY_INIT_DEFAULT, false, FD_EXEC_TEST_FEATURE_SET_INIT_DEFAULT} +#define FD_EXEC_TEST_ELF_LOADER_CTX_INIT_DEFAULT {false, FD_EXEC_TEST_ELF_BINARY_INIT_DEFAULT, false, FD_EXEC_TEST_FEATURE_SET_INIT_DEFAULT, 0} #define FD_EXEC_TEST_ELF_LOADER_EFFECTS_INIT_DEFAULT {NULL, 0, 0, 0, 0, 0, NULL} #define FD_EXEC_TEST_ELF_LOADER_FIXTURE_INIT_DEFAULT {false, FD_EXEC_TEST_ELF_LOADER_CTX_INIT_DEFAULT, false, FD_EXEC_TEST_ELF_LOADER_EFFECTS_INIT_DEFAULT} #define FD_EXEC_TEST_FEATURE_SET_INIT_ZERO {0, NULL} @@ -182,7 +183,7 @@ extern "C" { #define FD_EXEC_TEST_INSTR_EFFECTS_INIT_ZERO {0, false, 0, 0, NULL, 0, NULL} #define FD_EXEC_TEST_INSTR_FIXTURE_INIT_ZERO {false, FD_EXEC_TEST_INSTR_CONTEXT_INIT_ZERO, false, FD_EXEC_TEST_INSTR_EFFECTS_INIT_ZERO} #define FD_EXEC_TEST_ELF_BINARY_INIT_ZERO {NULL} -#define FD_EXEC_TEST_ELF_LOADER_CTX_INIT_ZERO {false, FD_EXEC_TEST_ELF_BINARY_INIT_ZERO, false, FD_EXEC_TEST_FEATURE_SET_INIT_ZERO} +#define FD_EXEC_TEST_ELF_LOADER_CTX_INIT_ZERO {false, FD_EXEC_TEST_ELF_BINARY_INIT_ZERO, false, FD_EXEC_TEST_FEATURE_SET_INIT_ZERO, 0} #define FD_EXEC_TEST_ELF_LOADER_EFFECTS_INIT_ZERO {NULL, 0, 0, 0, 0, 0, NULL} #define FD_EXEC_TEST_ELF_LOADER_FIXTURE_INIT_ZERO {false, FD_EXEC_TEST_ELF_LOADER_CTX_INIT_ZERO, false, FD_EXEC_TEST_ELF_LOADER_EFFECTS_INIT_ZERO} @@ -217,6 +218,7 @@ extern "C" { #define FD_EXEC_TEST_ELF_BINARY_DATA_TAG 1 #define FD_EXEC_TEST_ELF_LOADER_CTX_ELF_TAG 1 #define FD_EXEC_TEST_ELF_LOADER_CTX_FEATURES_TAG 2 +#define FD_EXEC_TEST_ELF_LOADER_CTX_ELF_SZ_TAG 3 #define FD_EXEC_TEST_ELF_LOADER_EFFECTS_RODATA_TAG 1 #define FD_EXEC_TEST_ELF_LOADER_EFFECTS_RODATA_SZ_TAG 2 #define FD_EXEC_TEST_ELF_LOADER_EFFECTS_TEXT_CNT_TAG 4 @@ -308,7 +310,8 @@ X(a, POINTER, SINGULAR, BYTES, data, 1) #define FD_EXEC_TEST_ELF_LOADER_CTX_FIELDLIST(X, a) \ X(a, STATIC, OPTIONAL, MESSAGE, elf, 1) \ -X(a, STATIC, OPTIONAL, MESSAGE, features, 2) +X(a, STATIC, OPTIONAL, MESSAGE, features, 2) \ +X(a, STATIC, SINGULAR, UINT64, elf_sz, 3) #define FD_EXEC_TEST_ELF_LOADER_CTX_CALLBACK NULL #define FD_EXEC_TEST_ELF_LOADER_CTX_DEFAULT NULL #define fd_exec_test_elf_loader_ctx_t_elf_MSGTYPE fd_exec_test_elf_binary_t @@ -401,9 +404,12 @@ extern const pb_msgdesc_t fd_exec_test_elf_loader_fixture_t_msg; #define ORG_SOLANA_SEALEVEL_V1_INSTR_EFFECTS_INIT_DEFAULT FD_EXEC_TEST_INSTR_EFFECTS_INIT_DEFAULT #define ORG_SOLANA_SEALEVEL_V1_INSTR_FIXTURE_INIT_DEFAULT FD_EXEC_TEST_INSTR_FIXTURE_INIT_DEFAULT #define ORG_SOLANA_SEALEVEL_V1_ELF_BINARY_INIT_DEFAULT FD_EXEC_TEST_ELF_BINARY_INIT_DEFAULT +#define ORG_SOLANA_SEALEVEL_V1_ELF_LOADER_CTX_INIT_DEFAULT FD_EXEC_TEST_ELF_LOADER_CTX_INIT_DEFAULT +#define ORG_SOLANA_SEALEVEL_V1_ELF_LOADER_EFFECTS_INIT_DEFAULT FD_EXEC_TEST_ELF_LOADER_EFFECTS_INIT_DEFAULT #define ORG_SOLANA_SEALEVEL_V1_ELF_LOADER_FIXTURE_INIT_DEFAULT FD_EXEC_TEST_ELF_LOADER_FIXTURE_INIT_DEFAULT #define ORG_SOLANA_SEALEVEL_V1_FEATURE_SET_INIT_ZERO FD_EXEC_TEST_FEATURE_SET_INIT_ZERO #define ORG_SOLANA_SEALEVEL_V1_ACCT_STATE_INIT_ZERO FD_EXEC_TEST_ACCT_STATE_INIT_ZERO +#define ORG_SOLANA_SEALEVEL_V1_EPOCH_CONTEXT_INIT_ZERO FD_EXEC_TEST_EPOCH_CONTEXT_INIT_ZERO #define ORG_SOLANA_SEALEVEL_V1_SLOT_CONTEXT_INIT_ZERO FD_EXEC_TEST_SLOT_CONTEXT_INIT_ZERO #define ORG_SOLANA_SEALEVEL_V1_TXN_CONTEXT_INIT_ZERO FD_EXEC_TEST_TXN_CONTEXT_INIT_ZERO #define ORG_SOLANA_SEALEVEL_V1_INSTR_ACCT_INIT_ZERO FD_EXEC_TEST_INSTR_ACCT_INIT_ZERO diff --git a/src/flamenco/runtime/tests/fd_exec_test.proto b/src/flamenco/runtime/tests/fd_exec_test.proto index f4b03bbde3..6faca681ae 100644 --- a/src/flamenco/runtime/tests/fd_exec_test.proto +++ b/src/flamenco/runtime/tests/fd_exec_test.proto @@ -124,6 +124,7 @@ message ELFBinary { message ELFLoaderCtx { ELFBinary elf = 1; FeatureSet features = 2; + uint64 elf_sz = 3; } // Captures the results of a elf binary load.