Skip to content

Commit 01781bb

Browse files
authored
v3.0: Fix - Restrict address space of sysvar syscalls in SIMD-0219 (backport of #7832) (#7959)
* Fix - Restrict address space of sysvar syscalls in SIMD-0219 (#7832) * Restrict address space of sysvar syscalls as well (similar to CPI). * Adds a test for the new restriction. * Rekeys stricter_abi_and_runtime_constraints.
1 parent bec0de9 commit 01781bb

File tree

4 files changed

+52
-5
lines changed

4 files changed

+52
-5
lines changed

feature-set/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -751,7 +751,7 @@ pub mod apply_cost_tracker_during_replay {
751751
}
752752

753753
pub mod stricter_abi_and_runtime_constraints {
754-
solana_pubkey::declare_id!("C37iaPi6VE4CZDueU1vL8y6pGp5i8amAbEsF31xzz723");
754+
solana_pubkey::declare_id!("CxeBn9PVeeXbmjbNwLv6U4C6svNxnC4JX6mfkvgeMocM");
755755
}
756756

757757
pub mod add_set_tx_loaded_accounts_data_size_instruction {
@@ -1277,7 +1277,7 @@ pub static FEATURE_NAMES: LazyLock<AHashMap<Pubkey, &'static str>> = LazyLock::n
12771277
(clean_up_delegation_errors::id(), "Return InsufficientDelegation instead of InsufficientFunds or InsufficientStake where applicable #31206"),
12781278
(vote_state_add_vote_latency::id(), "replace Lockout with LandedVote (including vote latency) in vote state #31264"),
12791279
(checked_arithmetic_in_fee_validation::id(), "checked arithmetic in fee validation #31273"),
1280-
(stricter_abi_and_runtime_constraints::id(), "use memory regions to map account data into the rbpf vm instead of copying the data"),
1280+
(stricter_abi_and_runtime_constraints::id(), "SIMD-0219: Stricter ABI and Runtime Constraints"),
12811281
(last_restart_slot_sysvar::id(), "enable new sysvar last_restart_slot"),
12821282
(reduce_stake_warmup_cooldown::id(), "reduce stake warmup cooldown from 25% to 9%"),
12831283
(revise_turbine_epoch_stakes::id(), "revise turbine epoch stakes"),

programs/sbf/rust/sysvar/src/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,16 @@ pub fn process_instruction(
209209

210210
Ok(())
211211
}
212+
Some(&4) => {
213+
// Attempt to store the result in the input region instead of the stack or heap
214+
unsafe {
215+
solana_define_syscall::definitions::sol_get_epoch_rewards_sysvar(
216+
accounts[2].data.borrow_mut().as_mut_ptr(),
217+
)
218+
};
219+
220+
Ok(())
221+
}
212222
_ => Err(ProgramError::InvalidInstructionData),
213223
}
214224
}

programs/sbf/tests/sysvar.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,21 @@ fn test_sysvar_syscalls() {
6969
&authority_keypair,
7070
"solana_sbf_rust_sysvar",
7171
);
72+
let dummy_account_key = Pubkey::new_unique();
73+
bank.store_account(
74+
&dummy_account_key,
75+
&solana_account::AccountSharedData::new(1, 32, &program_id),
76+
);
7277
bank.freeze();
78+
let blockhash = bank.last_blockhash();
7379

7480
for ix_discriminator in 0..4 {
7581
let instruction = Instruction::new_with_bincode(
7682
program_id,
7783
&[ix_discriminator],
7884
vec![
7985
AccountMeta::new(mint_keypair.pubkey(), true),
80-
AccountMeta::new(Pubkey::new_unique(), false),
86+
AccountMeta::new(dummy_account_key, false),
8187
AccountMeta::new_readonly(clock::id(), false),
8288
AccountMeta::new_readonly(epoch_schedule::id(), false),
8389
AccountMeta::new_readonly(instructions::id(), false),
@@ -90,11 +96,27 @@ fn test_sysvar_syscalls() {
9096
AccountMeta::new_readonly(epoch_rewards::id(), false),
9197
],
9298
);
93-
let blockhash = bank.last_blockhash();
9499
let message = Message::new(&[instruction], Some(&mint_keypair.pubkey()));
95100
let transaction = Transaction::new(&[&mint_keypair], message, blockhash);
96101
let sanitized_tx = RuntimeTransaction::from_transaction_for_tests(transaction);
97102
let result = bank.simulate_transaction(&sanitized_tx, false);
98103
assert!(result.result.is_ok());
99104
}
105+
106+
// Storing the result of get_sysvar() in the input region is not allowed
107+
// because of the 16 byte alignment requirement of the EpochRewards sysvar.
108+
let instruction = Instruction::new_with_bincode(
109+
program_id,
110+
&[4],
111+
vec![
112+
AccountMeta::new(mint_keypair.pubkey(), true),
113+
AccountMeta::new_readonly(epoch_rewards::id(), false),
114+
AccountMeta::new(dummy_account_key, false),
115+
],
116+
);
117+
let message = Message::new(&[instruction], Some(&mint_keypair.pubkey()));
118+
let transaction = Transaction::new(&[&mint_keypair], message, blockhash);
119+
let sanitized_tx = RuntimeTransaction::from_transaction_for_tests(transaction);
120+
let result = bank.simulate_transaction(&sanitized_tx, false);
121+
assert!(result.result.is_err());
100122
}

syscalls/src/sysvar.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use {
22
super::*, crate::translate_mut,
3-
solana_program_runtime::execution_budget::SVMTransactionExecutionCost,
3+
solana_program_runtime::execution_budget::SVMTransactionExecutionCost, solana_sbpf::ebpf,
44
};
55

66
fn get_sysvar<T: std::fmt::Debug + SysvarSerialize + Clone>(
@@ -17,6 +17,14 @@ fn get_sysvar<T: std::fmt::Debug + SysvarSerialize + Clone>(
1717
.sysvar_base_cost
1818
.saturating_add(size_of::<T>() as u64),
1919
)?;
20+
21+
if var_addr >= ebpf::MM_INPUT_START
22+
&& invoke_context
23+
.get_feature_set()
24+
.stricter_abi_and_runtime_constraints
25+
{
26+
return Err(SyscallError::InvalidPointer.into());
27+
}
2028
translate_mut!(
2129
memory_mapping,
2230
check_aligned,
@@ -203,6 +211,13 @@ declare_builtin_function!(
203211
.saturating_add(std::cmp::max(sysvar_buf_cost, mem_op_base_cost)),
204212
)?;
205213

214+
if var_addr >= ebpf::MM_INPUT_START
215+
&& invoke_context
216+
.get_feature_set()
217+
.stricter_abi_and_runtime_constraints
218+
{
219+
return Err(SyscallError::InvalidPointer.into());
220+
}
206221
// Abort: "Not all bytes in VM memory range `[var_addr, var_addr + length)` are writable."
207222
translate_mut!(
208223
memory_mapping,

0 commit comments

Comments
 (0)