From 8f1d4c1665611153651d7cc2957fef2c20da2740 Mon Sep 17 00:00:00 2001 From: Jack May Date: Tue, 10 May 2022 22:22:49 -0700 Subject: [PATCH] Disallow deployment of deprecated _sol_alloc_free syscall (#24986) * Disallow deployment of deprecated _sol_alloc_free syscall * remove cli argument --- cli/src/program.rs | 2 +- programs/bpf/benches/bpf_loader.rs | 6 +- programs/bpf/c/src/alloc/alloc.c | 31 +++++-- programs/bpf/rust/128bit/src/lib.rs | 3 +- programs/bpf/rust/alloc/src/lib.rs | 5 +- programs/bpf/rust/call_depth/src/lib.rs | 5 +- programs/bpf/rust/iter/src/lib.rs | 5 +- programs/bpf/rust/many_args/src/lib.rs | 3 +- programs/bpf/rust/membuiltins/src/lib.rs | 3 +- programs/bpf/rust/param_passing/src/lib.rs | 5 +- .../bpf/rust/secp256k1_recover/src/lib.rs | 3 +- programs/bpf/rust/sha/src/lib.rs | 3 +- programs/bpf/rust/zk_token_elgamal/src/lib.rs | 3 +- programs/bpf/tests/programs.rs | 90 ++++++++++++++++++- programs/bpf_loader/src/lib.rs | 30 +++++-- programs/bpf_loader/src/syscalls.rs | 5 +- rbpf-cli/src/main.rs | 2 +- sdk/bpf/c/inc/sol/string.h | 57 +++++++++--- sdk/src/feature_set.rs | 5 ++ 19 files changed, 223 insertions(+), 43 deletions(-) diff --git a/cli/src/program.rs b/cli/src/program.rs index 53e82f179af4aa..3f1a61ffcbee9f 100644 --- a/cli/src/program.rs +++ b/cli/src/program.rs @@ -2044,7 +2044,7 @@ fn read_and_verify_elf(program_location: &str) -> Result, Box::jit_compile(&mut executable).unwrap(); @@ -228,7 +228,7 @@ fn bench_create_vm(bencher: &mut Bencher) { &elf, None, Config::default(), - register_syscalls(invoke_context).unwrap(), + register_syscalls(invoke_context, true).unwrap(), ) .unwrap(); @@ -263,7 +263,7 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) { &elf, None, Config::default(), - register_syscalls(invoke_context).unwrap(), + register_syscalls(invoke_context, true).unwrap(), ) .unwrap(); let compute_meter = invoke_context.get_compute_meter(); diff --git a/programs/bpf/c/src/alloc/alloc.c b/programs/bpf/c/src/alloc/alloc.c index f7b3b93bbb44cf..db6157e19311b1 100644 --- a/programs/bpf/c/src/alloc/alloc.c +++ b/programs/bpf/c/src/alloc/alloc.c @@ -9,7 +9,7 @@ extern uint64_t entrypoint(const uint8_t *input) { // Confirm large allocation fails void *ptr = sol_calloc(1, UINT64_MAX); if (ptr != NULL) { - sol_log("Error: Alloc of very larger buffer should fail"); + sol_log("Error: Alloc of very large type should fail"); sol_panic(); } } @@ -18,7 +18,7 @@ extern uint64_t entrypoint(const uint8_t *input) { // Confirm large allocation fails void *ptr = sol_calloc(UINT64_MAX, 1); if (ptr != NULL) { - sol_log("Error: Alloc of very larger buffer should fail"); + sol_log("Error: Alloc of very large number of items should fail"); sol_panic(); } } @@ -42,16 +42,37 @@ extern uint64_t entrypoint(const uint8_t *input) { sol_log("Error: Alloc failed"); sol_panic(); } - for (int i = 0; i < iters; i++) { + for (uint64_t i = 0; i < iters; i++) { *(ptr + i) = i; } - for (int i = 0; i < iters; i++) { + for (uint64_t i = 0; i < iters; i++) { sol_assert(*(ptr + i) == i); } - sol_log_64(0x3, 0, 0, 0, *(ptr + 42)); sol_assert(*(ptr + 42) == 42); sol_free(ptr); } + // Alloc to exhaustion + + for (uint64_t i = 0; i < 31; i++) { + uint8_t *ptr = sol_calloc(1024, 1); + if (ptr == NULL) { + sol_log("large alloc failed"); + sol_panic(); + } + } + for (uint64_t i = 0; i < 760; i++) { + uint8_t *ptr = sol_calloc(1, 1); + if (ptr == NULL) { + sol_log("small alloc failed"); + sol_panic(); + } + } + uint8_t *ptr = sol_calloc(1, 1); + if (ptr != NULL) { + sol_log("final alloc did not fail"); + sol_panic(); + } + return SUCCESS; } diff --git a/programs/bpf/rust/128bit/src/lib.rs b/programs/bpf/rust/128bit/src/lib.rs index 49a44d744eef14..dd81952301eb95 100644 --- a/programs/bpf/rust/128bit/src/lib.rs +++ b/programs/bpf/rust/128bit/src/lib.rs @@ -1,7 +1,7 @@ //! Example Rust-based BPF program tests loop iteration extern crate solana_program; -use solana_program::{custom_panic_default, entrypoint::SUCCESS}; +use solana_program::{custom_heap_default, custom_panic_default, entrypoint::SUCCESS}; #[no_mangle] pub extern "C" fn entrypoint(_input: *mut u8) -> u64 { @@ -50,6 +50,7 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> u64 { SUCCESS } +custom_heap_default!(); custom_panic_default!(); #[cfg(test)] diff --git a/programs/bpf/rust/alloc/src/lib.rs b/programs/bpf/rust/alloc/src/lib.rs index 57d84bad7a60d2..09919b12e45881 100644 --- a/programs/bpf/rust/alloc/src/lib.rs +++ b/programs/bpf/rust/alloc/src/lib.rs @@ -3,7 +3,9 @@ #[macro_use] extern crate alloc; use { - solana_program::{custom_panic_default, entrypoint::SUCCESS, log::sol_log_64, msg}, + solana_program::{ + custom_heap_default, custom_panic_default, entrypoint::SUCCESS, log::sol_log_64, msg, + }, std::{alloc::Layout, mem}, }; @@ -83,6 +85,7 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> u64 { SUCCESS } +custom_heap_default!(); custom_panic_default!(); #[cfg(test)] diff --git a/programs/bpf/rust/call_depth/src/lib.rs b/programs/bpf/rust/call_depth/src/lib.rs index 888c491d98a2f6..42e32df6d634a2 100644 --- a/programs/bpf/rust/call_depth/src/lib.rs +++ b/programs/bpf/rust/call_depth/src/lib.rs @@ -1,6 +1,8 @@ //! Example Rust-based BPF program that tests call depth and stack usage -use solana_program::{custom_panic_default, entrypoint::SUCCESS, log::sol_log_64, msg}; +use solana_program::{ + custom_heap_default, custom_panic_default, entrypoint::SUCCESS, log::sol_log_64, msg, +}; #[inline(never)] pub fn recurse(data: &mut [u8]) { @@ -26,4 +28,5 @@ pub unsafe extern "C" fn entrypoint(input: *mut u8) -> u64 { SUCCESS } +custom_heap_default!(); custom_panic_default!(); diff --git a/programs/bpf/rust/iter/src/lib.rs b/programs/bpf/rust/iter/src/lib.rs index a262deb89f42f7..3fda481a4b24bd 100644 --- a/programs/bpf/rust/iter/src/lib.rs +++ b/programs/bpf/rust/iter/src/lib.rs @@ -1,7 +1,9 @@ //! Example Rust-based BPF program tests loop iteration extern crate solana_program; -use solana_program::{custom_panic_default, entrypoint::SUCCESS, log::sol_log_64}; +use solana_program::{ + custom_heap_default, custom_panic_default, entrypoint::SUCCESS, log::sol_log_64, +}; #[no_mangle] pub extern "C" fn entrypoint(_input: *mut u8) -> u64 { @@ -18,6 +20,7 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> u64 { SUCCESS } +custom_heap_default!(); custom_panic_default!(); #[cfg(test)] diff --git a/programs/bpf/rust/many_args/src/lib.rs b/programs/bpf/rust/many_args/src/lib.rs index 0c27b1ba32010a..6d8819b1accbd5 100644 --- a/programs/bpf/rust/many_args/src/lib.rs +++ b/programs/bpf/rust/many_args/src/lib.rs @@ -2,7 +2,7 @@ mod helper; extern crate solana_program; -use solana_program::{custom_panic_default, entrypoint::SUCCESS, msg}; +use solana_program::{custom_heap_default, custom_panic_default, entrypoint::SUCCESS, msg}; #[no_mangle] pub extern "C" fn entrypoint(_input: *mut u8) -> u64 { @@ -26,6 +26,7 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> u64 { SUCCESS } +custom_heap_default!(); custom_panic_default!(); #[cfg(test)] diff --git a/programs/bpf/rust/membuiltins/src/lib.rs b/programs/bpf/rust/membuiltins/src/lib.rs index 0ef07a111044e6..440c89074d3af8 100644 --- a/programs/bpf/rust/membuiltins/src/lib.rs +++ b/programs/bpf/rust/membuiltins/src/lib.rs @@ -6,7 +6,7 @@ extern crate compiler_builtins; use { solana_bpf_rust_mem::{run_mem_tests, MemOps}, - solana_program::{custom_panic_default, entrypoint::SUCCESS}, + solana_program::{custom_heap_default, custom_panic_default, entrypoint::SUCCESS}, }; #[no_mangle] @@ -38,4 +38,5 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> u64 { SUCCESS } +custom_heap_default!(); custom_panic_default!(); diff --git a/programs/bpf/rust/param_passing/src/lib.rs b/programs/bpf/rust/param_passing/src/lib.rs index 3c5006620f6021..590fbf13f90849 100644 --- a/programs/bpf/rust/param_passing/src/lib.rs +++ b/programs/bpf/rust/param_passing/src/lib.rs @@ -3,7 +3,9 @@ extern crate solana_program; use { solana_bpf_rust_param_passing_dep::{Data, TestDep}, - solana_program::{custom_panic_default, entrypoint::SUCCESS, log::sol_log_64}, + solana_program::{ + custom_heap_default, custom_panic_default, entrypoint::SUCCESS, log::sol_log_64, + }, }; #[no_mangle] @@ -25,6 +27,7 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> u64 { SUCCESS } +custom_heap_default!(); custom_panic_default!(); #[cfg(test)] diff --git a/programs/bpf/rust/secp256k1_recover/src/lib.rs b/programs/bpf/rust/secp256k1_recover/src/lib.rs index 2e9ccdbdc76b02..58fe2c7b96ba0f 100644 --- a/programs/bpf/rust/secp256k1_recover/src/lib.rs +++ b/programs/bpf/rust/secp256k1_recover/src/lib.rs @@ -1,7 +1,7 @@ //! Secp256k1Recover Syscall test extern crate solana_program; -use solana_program::{custom_panic_default, msg}; +use solana_program::{custom_heap_default, custom_panic_default, msg}; fn test_secp256k1_recover() { use solana_program::secp256k1_recover::secp256k1_recover; @@ -41,4 +41,5 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> u64 { 0 } +custom_heap_default!(); custom_panic_default!(); diff --git a/programs/bpf/rust/sha/src/lib.rs b/programs/bpf/rust/sha/src/lib.rs index a3b5e7e7d61a56..bc1579b22bd744 100644 --- a/programs/bpf/rust/sha/src/lib.rs +++ b/programs/bpf/rust/sha/src/lib.rs @@ -1,7 +1,7 @@ //! SHA Syscall test extern crate solana_program; -use solana_program::{custom_panic_default, msg}; +use solana_program::{custom_heap_default, custom_panic_default, msg}; fn test_sha256_hasher() { use solana_program::hash::{hashv, Hasher}; @@ -39,6 +39,7 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> u64 { 0 } +custom_heap_default!(); custom_panic_default!(); #[cfg(test)] diff --git a/programs/bpf/rust/zk_token_elgamal/src/lib.rs b/programs/bpf/rust/zk_token_elgamal/src/lib.rs index e48404bf821280..9bffd741118594 100644 --- a/programs/bpf/rust/zk_token_elgamal/src/lib.rs +++ b/programs/bpf/rust/zk_token_elgamal/src/lib.rs @@ -2,7 +2,7 @@ extern crate solana_program; use { - solana_program::{custom_panic_default, msg}, + solana_program::{custom_heap_default, custom_panic_default, msg}, solana_zk_token_sdk::zk_token_elgamal::{ ops, pod::{ElGamalCiphertext, Zeroable}, @@ -50,4 +50,5 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> u64 { 0 } +custom_heap_default!(); custom_panic_default!(); diff --git a/programs/bpf/tests/programs.rs b/programs/bpf/tests/programs.rs index 70e0a96bcd661b..4908c0c9ed4d59 100644 --- a/programs/bpf/tests/programs.rs +++ b/programs/bpf/tests/programs.rs @@ -40,7 +40,7 @@ use { }, }, solana_sdk::{ - account::{AccountSharedData, ReadableAccount}, + account::{AccountSharedData, ReadableAccount, WritableAccount}, account_utils::StateMut, bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable, client::SyncClient, @@ -226,7 +226,7 @@ fn run_program(name: &str) -> u64 { &data, None, config, - register_syscalls(invoke_context).unwrap(), + register_syscalls(invoke_context, false /* no sol_alloc_free */).unwrap(), ) .unwrap(); Executable::::jit_compile(&mut executable).unwrap(); @@ -563,6 +563,10 @@ fn test_program_bpf_loader_deprecated() { .accounts .remove(&solana_sdk::feature_set::disable_deprecated_loader::id()) .unwrap(); + genesis_config + .accounts + .remove(&solana_sdk::feature_set::disable_deploy_of_alloc_free_syscall::id()) + .unwrap(); let mut bank = Bank::new_for_tests(&genesis_config); let (name, id, entrypoint) = solana_bpf_loader_deprecated_program!(); bank.add_builtin(&name, &id, entrypoint); @@ -581,6 +585,84 @@ fn test_program_bpf_loader_deprecated() { } } +#[test] +fn test_sol_alloc_free_no_longer_deployable() { + solana_logger::setup(); + + let program_keypair = Keypair::new(); + let program_address = program_keypair.pubkey(); + let loader_address = bpf_loader_deprecated::id(); + + let GenesisConfigInfo { + genesis_config, + mint_keypair, + .. + } = create_genesis_config(50); + let mut bank = Bank::new_for_tests(&genesis_config); + + bank.deactivate_feature(&solana_sdk::feature_set::disable_deprecated_loader::id()); + let (name, id, entrypoint) = solana_bpf_loader_deprecated_program!(); + bank.add_builtin(&name, &id, entrypoint); + + // Populate loader account with elf that depends on _sol_alloc_free syscall + let elf = read_bpf_program("solana_bpf_rust_deprecated_loader"); + let mut program_account = AccountSharedData::new(1, elf.len(), &loader_address); + program_account + .data_as_mut_slice() + .get_mut(..) + .unwrap() + .copy_from_slice(&elf); + bank.store_account(&program_address, &program_account); + + let finalize_tx = Transaction::new( + &[&mint_keypair, &program_keypair], + Message::new( + &[loader_instruction::finalize( + &program_keypair.pubkey(), + &loader_address, + )], + Some(&mint_keypair.pubkey()), + ), + bank.last_blockhash(), + ); + + let invoke_tx = Transaction::new( + &[&mint_keypair], + Message::new( + &[Instruction::new_with_bytes( + program_address, + &[1], + vec![AccountMeta::new(mint_keypair.pubkey(), true)], + )], + Some(&mint_keypair.pubkey()), + ), + bank.last_blockhash(), + ); + + // Try and deploy a program that depends on _sol_alloc_free + assert_eq!( + bank.process_transaction(&finalize_tx).unwrap_err(), + TransactionError::InstructionError(0, InstructionError::InvalidAccountData) + ); + + // Enable _sol_alloc_free syscall + bank.deactivate_feature(&solana_sdk::feature_set::disable_deploy_of_alloc_free_syscall::id()); + bank.clear_signatures(); + + // Try and finalize the program now that sol_alloc_free is re-enabled + assert!(bank.process_transaction(&finalize_tx).is_ok()); + + // invoke the program + assert!(bank.process_transaction(&invoke_tx).is_ok()); + + // disable _sol_alloc_free + bank.deactivate_feature(&solana_sdk::feature_set::disable_deploy_of_alloc_free_syscall::id()); + bank.clear_signatures(); + + // invoke should still succeed on execute because the program is already deployed + assert!(bank.process_transaction(&invoke_tx).is_ok()); +} + #[test] fn test_program_bpf_duplicate_accounts() { solana_logger::setup(); @@ -1437,7 +1519,7 @@ fn assert_instruction_count() { { programs.extend_from_slice(&[ ("solana_bpf_rust_128bit", 584), - ("solana_bpf_rust_alloc", 4459), + ("solana_bpf_rust_alloc", 4581), ("solana_bpf_rust_custom_heap", 469), ("solana_bpf_rust_dep_crate", 2), ("solana_bpf_rust_external_spend", 338), @@ -1450,7 +1532,7 @@ fn assert_instruction_count() { ("solana_bpf_rust_rand", 429), ("solana_bpf_rust_sanity", 52290), ("solana_bpf_rust_secp256k1_recover", 25707), - ("solana_bpf_rust_sha", 25251), + ("solana_bpf_rust_sha", 25265), ]); } diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index 0f06e2f8461758..696325c6c51b58 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -42,9 +42,10 @@ use { entrypoint::{HEAP_LENGTH, SUCCESS}, feature_set::{ cap_accounts_data_len, disable_bpf_deprecated_load_instructions, - disable_bpf_unresolved_symbols_at_runtime, disable_deprecated_loader, - do_support_realloc, error_on_syscall_bpf_function_hash_collisions, - reduce_required_deploy_balance, reject_callx_r10, requestable_heap_size, + disable_bpf_unresolved_symbols_at_runtime, disable_deploy_of_alloc_free_syscall, + disable_deprecated_loader, do_support_realloc, + error_on_syscall_bpf_function_hash_collisions, reduce_required_deploy_balance, + reject_callx_r10, requestable_heap_size, }, instruction::{AccountMeta, InstructionError}, loader_instruction::LoaderInstruction, @@ -109,9 +110,11 @@ pub fn create_executor( invoke_context: &mut InvokeContext, use_jit: bool, reject_deployment_of_broken_elfs: bool, + disable_deploy_of_alloc_free_syscall: bool, ) -> Result, InstructionError> { let mut register_syscalls_time = Measure::start("register_syscalls_time"); - let register_syscall_result = syscalls::register_syscalls(invoke_context); + let register_syscall_result = + syscalls::register_syscalls(invoke_context, disable_deploy_of_alloc_free_syscall); register_syscalls_time.stop(); invoke_context.timings.create_executor_register_syscalls_us = invoke_context .timings @@ -383,6 +386,7 @@ fn process_instruction_common( invoke_context, use_jit, false, + true, // allow _sol_alloc_free syscall for execution )?; let transaction_context = &invoke_context.transaction_context; let instruction_context = transaction_context.get_current_instruction_context()?; @@ -626,6 +630,9 @@ fn process_loader_upgradeable_instruction( invoke_context, use_jit, true, + invoke_context + .feature_set + .is_active(&disable_deploy_of_alloc_free_syscall::id()), )?; invoke_context.update_executor(&new_program_id, executor); @@ -805,6 +812,9 @@ fn process_loader_upgradeable_instruction( invoke_context, use_jit, true, + invoke_context + .feature_set + .is_active(&disable_deploy_of_alloc_free_syscall::id()), )?; invoke_context.update_executor(&new_program_id, executor); @@ -1100,8 +1110,16 @@ fn process_loader_instruction( ic_msg!(invoke_context, "key[0] did not sign the transaction"); return Err(InstructionError::MissingRequiredSignature); } - let executor = - create_executor(first_instruction_account, 0, invoke_context, use_jit, true)?; + let executor = create_executor( + first_instruction_account, + 0, + invoke_context, + use_jit, + true, + invoke_context + .feature_set + .is_active(&disable_deploy_of_alloc_free_syscall::id()), + )?; let transaction_context = &invoke_context.transaction_context; let instruction_context = transaction_context.get_current_instruction_context()?; let mut program = diff --git a/programs/bpf_loader/src/syscalls.rs b/programs/bpf_loader/src/syscalls.rs index 660c1ffbf314fa..9a97d31b34a46d 100644 --- a/programs/bpf_loader/src/syscalls.rs +++ b/programs/bpf_loader/src/syscalls.rs @@ -128,6 +128,7 @@ macro_rules! register_feature_gated_syscall { pub fn register_syscalls( invoke_context: &mut InvokeContext, + disable_deploy_of_alloc_free_syscall: bool, ) -> Result> { let secp256k1_recover_syscall_enabled = invoke_context .feature_set @@ -328,7 +329,9 @@ pub fn register_syscalls( )?; // Memory allocator - syscall_registry.register_syscall_by_name( + register_feature_gated_syscall!( + syscall_registry, + !disable_deploy_of_alloc_free_syscall, b"sol_alloc_free_", SyscallAllocFree::init, SyscallAllocFree::call, diff --git a/rbpf-cli/src/main.rs b/rbpf-cli/src/main.rs index ff8f965372cca5..a19ef99284de15 100644 --- a/rbpf-cli/src/main.rs +++ b/rbpf-cli/src/main.rs @@ -270,7 +270,7 @@ native machine code before execting it in the virtual machine.", file.seek(SeekFrom::Start(0)).unwrap(); let mut contents = Vec::new(); file.read_to_end(&mut contents).unwrap(); - let syscall_registry = register_syscalls(&mut invoke_context).unwrap(); + let syscall_registry = register_syscalls(&mut invoke_context, true).unwrap(); let mut executable = if magic == [0x7f, 0x45, 0x4c, 0x46] { Executable::::from_elf( &contents, diff --git a/sdk/bpf/c/inc/sol/string.h b/sdk/bpf/c/inc/sol/string.h index 8a329a67caab5c..159c9fd9e2df26 100644 --- a/sdk/bpf/c/inc/sol/string.h +++ b/sdk/bpf/c/inc/sol/string.h @@ -56,30 +56,63 @@ static size_t sol_strlen(const char *s) { } /** - * Internal memory alloc/free function + * Start address of the memory region used for program heap. */ -#ifndef SOL_SBFV2 -void* sol_alloc_free_(uint64_t, void *); -#else -typedef void*(*sol_alloc_free__pointer_type)(uint64_t, void *); -static void* sol_alloc_free_(uint64_t arg1, void * arg2) { - sol_alloc_free__pointer_type sol_alloc_free__pointer = (sol_alloc_free__pointer_type) 2213547663; - return sol_alloc_free__pointer(arg1, arg2); -} -#endif +#define HEAP_START_ADDRESS (0x300000000) +/** + * Length of the heap memory region used for program heap. + */ +#define HEAP_LENGTH (32 * 1024) /** * Alloc zero-initialized memory */ static void *sol_calloc(size_t nitems, size_t size) { - return sol_alloc_free_(nitems * size, 0); + // Bump allocator + uint64_t* pos_ptr = (uint64_t*)HEAP_START_ADDRESS; + + uint64_t pos = *pos_ptr; + if (pos == 0) { + /** First time, set starting position */ + pos = HEAP_START_ADDRESS + HEAP_LENGTH; + } + + uint64_t bytes = (uint64_t)(nitems * size); + if (size == 0 || + !(nitems == 0 || size == 0) && + !(nitems == bytes / size)) { + /** Overflow */ + return NULL; + } + if (pos < bytes) { + /** Saturated */ + pos = 0; + } else { + pos -= bytes; + } + + uint64_t align = size; + align--; + align |= align >> 1; + align |= align >> 2; + align |= align >> 4; + align |= align >> 8; + align |= align >> 16; + align |= align >> 32; + align++; + pos &= ~(align - 1); + if (pos < HEAP_START_ADDRESS + sizeof(uint8_t*)) { + return NULL; + } + *pos_ptr = pos; + return (void*)pos; } /** * Deallocates the memory previously allocated by sol_calloc */ static void sol_free(void *ptr) { - (void) sol_alloc_free_(0, ptr); + // I'm a bump allocator, I don't free } #ifdef __cplusplus diff --git a/sdk/src/feature_set.rs b/sdk/src/feature_set.rs index fd6bd35efa8d80..d5aa1b09f86816 100644 --- a/sdk/src/feature_set.rs +++ b/sdk/src/feature_set.rs @@ -396,6 +396,10 @@ pub mod stake_raise_minimum_delegation_to_1_sol { solana_sdk::declare_id!("4xmyBuR2VCXzy9H6qYpH9ckfgnTuMDQFPFBfTs4eBCY1"); } +pub mod disable_deploy_of_alloc_free_syscall { + solana_sdk::declare_id!("79HWsX9rpnnJBPcdNURVqygpMAfxdrAirzAGAVmf92im"); +} + lazy_static! { /// Map of feature identifiers to user-visible description pub static ref FEATURE_NAMES: HashMap = [ @@ -488,6 +492,7 @@ lazy_static! { (stake_allow_zero_undelegated_amount::id(), "Allow zero-lamport undelegated amount for initialized stakes #24670"), (require_static_program_ids_in_transaction::id(), "require static program ids in versioned transactions"), (stake_raise_minimum_delegation_to_1_sol::id(), "Raise minimum stake delegation to 1.0 SOL #24357"), + (disable_deploy_of_alloc_free_syscall::id(), "disable new deployments of deprecated sol_alloc_free_ syscall"), /*************** ADD NEW FEATURES HERE ***************/ ] .iter()