Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions feature-set/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,7 @@ pub mod apply_cost_tracker_during_replay {
}

pub mod stricter_abi_and_runtime_constraints {
solana_pubkey::declare_id!("C37iaPi6VE4CZDueU1vL8y6pGp5i8amAbEsF31xzz723");
solana_pubkey::declare_id!("CxeBn9PVeeXbmjbNwLv6U4C6svNxnC4JX6mfkvgeMocM");
}

pub mod add_set_tx_loaded_accounts_data_size_instruction {
Expand Down Expand Up @@ -1277,7 +1277,7 @@ pub static FEATURE_NAMES: LazyLock<AHashMap<Pubkey, &'static str>> = LazyLock::n
(clean_up_delegation_errors::id(), "Return InsufficientDelegation instead of InsufficientFunds or InsufficientStake where applicable #31206"),
(vote_state_add_vote_latency::id(), "replace Lockout with LandedVote (including vote latency) in vote state #31264"),
(checked_arithmetic_in_fee_validation::id(), "checked arithmetic in fee validation #31273"),
(stricter_abi_and_runtime_constraints::id(), "use memory regions to map account data into the rbpf vm instead of copying the data"),
(stricter_abi_and_runtime_constraints::id(), "SIMD-0219: Stricter ABI and Runtime Constraints"),
(last_restart_slot_sysvar::id(), "enable new sysvar last_restart_slot"),
(reduce_stake_warmup_cooldown::id(), "reduce stake warmup cooldown from 25% to 9%"),
(revise_turbine_epoch_stakes::id(), "revise turbine epoch stakes"),
Expand Down
10 changes: 10 additions & 0 deletions programs/sbf/rust/sysvar/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,16 @@ pub fn process_instruction(

Ok(())
}
Some(&4) => {
// Attempt to store the result in the input region instead of the stack or heap
unsafe {
solana_define_syscall::definitions::sol_get_epoch_rewards_sysvar(
accounts[2].data.borrow_mut().as_mut_ptr(),
)
};

Ok(())
}
_ => Err(ProgramError::InvalidInstructionData),
}
}
26 changes: 24 additions & 2 deletions programs/sbf/tests/sysvar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,21 @@ fn test_sysvar_syscalls() {
&authority_keypair,
"solana_sbf_rust_sysvar",
);
let dummy_account_key = Pubkey::new_unique();
bank.store_account(
&dummy_account_key,
&solana_account::AccountSharedData::new(1, 32, &program_id),
);
bank.freeze();
let blockhash = bank.last_blockhash();

for ix_discriminator in 0..4 {
let instruction = Instruction::new_with_bincode(
program_id,
&[ix_discriminator],
vec![
AccountMeta::new(mint_keypair.pubkey(), true),
AccountMeta::new(Pubkey::new_unique(), false),
AccountMeta::new(dummy_account_key, false),
AccountMeta::new_readonly(clock::id(), false),
AccountMeta::new_readonly(epoch_schedule::id(), false),
AccountMeta::new_readonly(instructions::id(), false),
Expand All @@ -90,11 +96,27 @@ fn test_sysvar_syscalls() {
AccountMeta::new_readonly(epoch_rewards::id(), false),
],
);
let blockhash = bank.last_blockhash();
let message = Message::new(&[instruction], Some(&mint_keypair.pubkey()));
let transaction = Transaction::new(&[&mint_keypair], message, blockhash);
let sanitized_tx = RuntimeTransaction::from_transaction_for_tests(transaction);
let result = bank.simulate_transaction(&sanitized_tx, false);
assert!(result.result.is_ok());
}

// Storing the result of get_sysvar() in the input region is not allowed
// because of the 16 byte alignment requirement of the EpochRewards sysvar.
let instruction = Instruction::new_with_bincode(
program_id,
&[4],
vec![
AccountMeta::new(mint_keypair.pubkey(), true),
AccountMeta::new_readonly(epoch_rewards::id(), false),
AccountMeta::new(dummy_account_key, false),
],
);
let message = Message::new(&[instruction], Some(&mint_keypair.pubkey()));
let transaction = Transaction::new(&[&mint_keypair], message, blockhash);
let sanitized_tx = RuntimeTransaction::from_transaction_for_tests(transaction);
let result = bank.simulate_transaction(&sanitized_tx, false);
assert!(result.result.is_err());
}
17 changes: 16 additions & 1 deletion syscalls/src/sysvar.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use {
super::*, crate::translate_mut,
solana_program_runtime::execution_budget::SVMTransactionExecutionCost,
solana_program_runtime::execution_budget::SVMTransactionExecutionCost, solana_sbpf::ebpf,
};

fn get_sysvar<T: std::fmt::Debug + SysvarSerialize + Clone>(
Expand All @@ -17,6 +17,14 @@ fn get_sysvar<T: std::fmt::Debug + SysvarSerialize + Clone>(
.sysvar_base_cost
.saturating_add(size_of::<T>() as u64),
)?;

if var_addr >= ebpf::MM_INPUT_START
&& invoke_context
.get_feature_set()
.stricter_abi_and_runtime_constraints
{
return Err(SyscallError::InvalidPointer.into());
}
translate_mut!(
memory_mapping,
check_aligned,
Expand Down Expand Up @@ -203,6 +211,13 @@ declare_builtin_function!(
.saturating_add(std::cmp::max(sysvar_buf_cost, mem_op_base_cost)),
)?;

if var_addr >= ebpf::MM_INPUT_START
&& invoke_context
.get_feature_set()
.stricter_abi_and_runtime_constraints
{
return Err(SyscallError::InvalidPointer.into());
}
// Abort: "Not all bytes in VM memory range `[var_addr, var_addr + length)` are writable."
translate_mut!(
memory_mapping,
Expand Down
Loading