* Retain alloc'd and updated data in cpi (#16850)
(cherry picked from commit 9b3a59f030
)
# Conflicts:
# programs/bpf_loader/src/syscalls.rs
# sdk/src/feature_set.rs
* resolve conflicts
Co-authored-by: Jack May <jack@solana.com>
This commit is contained in:
@ -374,6 +374,32 @@ fn process_instruction(
|
|||||||
accounts[INVOKED_ARGUMENT_INDEX].data.borrow_mut()[..NUM_BYTES]
|
accounts[INVOKED_ARGUMENT_INDEX].data.borrow_mut()[..NUM_BYTES]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
msg!("Create account and init data");
|
||||||
|
{
|
||||||
|
let from_lamports = accounts[FROM_INDEX].lamports();
|
||||||
|
let to_lamports = accounts[DERIVED_KEY2_INDEX].lamports();
|
||||||
|
|
||||||
|
let instruction = create_instruction(
|
||||||
|
*accounts[INVOKED_PROGRAM_INDEX].key,
|
||||||
|
&[
|
||||||
|
(accounts[FROM_INDEX].key, true, true),
|
||||||
|
(accounts[DERIVED_KEY2_INDEX].key, true, false),
|
||||||
|
(accounts[SYSTEM_PROGRAM_INDEX].key, false, false),
|
||||||
|
],
|
||||||
|
vec![CREATE_AND_INIT, bump_seed2],
|
||||||
|
);
|
||||||
|
invoke(&instruction, accounts)?;
|
||||||
|
|
||||||
|
assert_eq!(accounts[FROM_INDEX].lamports(), from_lamports - 1);
|
||||||
|
assert_eq!(accounts[DERIVED_KEY2_INDEX].lamports(), to_lamports + 1);
|
||||||
|
let data = accounts[DERIVED_KEY2_INDEX].try_borrow_mut_data()?;
|
||||||
|
assert_eq!(data[0], 0x0e);
|
||||||
|
assert_eq!(data[MAX_PERMITTED_DATA_INCREASE - 1], 0x0f);
|
||||||
|
for i in 1..20 {
|
||||||
|
assert_eq!(data[i], i as u8);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
TEST_PRIVILEGE_ESCALATION_SIGNER => {
|
TEST_PRIVILEGE_ESCALATION_SIGNER => {
|
||||||
msg!("Test privilege escalation signer");
|
msg!("Test privilege escalation signer");
|
||||||
|
@ -17,6 +17,7 @@ pub const VERIFY_PRIVILEGE_DEESCALATION: u8 = 8;
|
|||||||
pub const VERIFY_PRIVILEGE_DEESCALATION_ESCALATION_SIGNER: u8 = 9;
|
pub const VERIFY_PRIVILEGE_DEESCALATION_ESCALATION_SIGNER: u8 = 9;
|
||||||
pub const VERIFY_PRIVILEGE_DEESCALATION_ESCALATION_WRITABLE: u8 = 10;
|
pub const VERIFY_PRIVILEGE_DEESCALATION_ESCALATION_WRITABLE: u8 = 10;
|
||||||
pub const WRITE_ACCOUNT: u8 = 11;
|
pub const WRITE_ACCOUNT: u8 = 11;
|
||||||
|
pub const CREATE_AND_INIT: u8 = 12;
|
||||||
|
|
||||||
pub fn create_instruction(
|
pub fn create_instruction(
|
||||||
program_id: Pubkey,
|
program_id: Pubkey,
|
||||||
|
@ -6,11 +6,12 @@ use crate::instruction::*;
|
|||||||
use solana_program::{
|
use solana_program::{
|
||||||
account_info::AccountInfo,
|
account_info::AccountInfo,
|
||||||
bpf_loader, entrypoint,
|
bpf_loader, entrypoint,
|
||||||
entrypoint::ProgramResult,
|
entrypoint::{ProgramResult, MAX_PERMITTED_DATA_INCREASE},
|
||||||
msg,
|
msg,
|
||||||
program::{invoke, invoke_signed},
|
program::{invoke, invoke_signed},
|
||||||
program_error::ProgramError,
|
program_error::ProgramError,
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
|
system_instruction,
|
||||||
};
|
};
|
||||||
|
|
||||||
entrypoint!(process_instruction);
|
entrypoint!(process_instruction);
|
||||||
@ -236,6 +237,52 @@ fn process_instruction(
|
|||||||
accounts[ARGUMENT_INDEX].data.borrow_mut()[i as usize] = instruction_data[1];
|
accounts[ARGUMENT_INDEX].data.borrow_mut()[i as usize] = instruction_data[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
CREATE_AND_INIT => {
|
||||||
|
msg!("Create and init data");
|
||||||
|
{
|
||||||
|
const FROM_INDEX: usize = 0;
|
||||||
|
const DERIVED_KEY2_INDEX: usize = 1;
|
||||||
|
|
||||||
|
let from_lamports = accounts[FROM_INDEX].lamports();
|
||||||
|
let to_lamports = accounts[DERIVED_KEY2_INDEX].lamports();
|
||||||
|
assert_eq!(accounts[DERIVED_KEY2_INDEX].data_len(), 0);
|
||||||
|
assert!(solana_program::system_program::check_id(
|
||||||
|
accounts[DERIVED_KEY2_INDEX].owner
|
||||||
|
));
|
||||||
|
|
||||||
|
let bump_seed2 = instruction_data[1];
|
||||||
|
let instruction = system_instruction::create_account(
|
||||||
|
accounts[FROM_INDEX].key,
|
||||||
|
accounts[DERIVED_KEY2_INDEX].key,
|
||||||
|
1,
|
||||||
|
MAX_PERMITTED_DATA_INCREASE as u64,
|
||||||
|
program_id,
|
||||||
|
);
|
||||||
|
invoke_signed(
|
||||||
|
&instruction,
|
||||||
|
accounts,
|
||||||
|
&[&[b"Lil'", b"Bits", &[bump_seed2]]],
|
||||||
|
)?;
|
||||||
|
|
||||||
|
assert_eq!(accounts[FROM_INDEX].lamports(), from_lamports - 1);
|
||||||
|
assert_eq!(accounts[DERIVED_KEY2_INDEX].lamports(), to_lamports + 1);
|
||||||
|
assert_eq!(program_id, accounts[DERIVED_KEY2_INDEX].owner);
|
||||||
|
assert_eq!(
|
||||||
|
accounts[DERIVED_KEY2_INDEX].data_len(),
|
||||||
|
MAX_PERMITTED_DATA_INCREASE
|
||||||
|
);
|
||||||
|
let mut data = accounts[DERIVED_KEY2_INDEX].try_borrow_mut_data()?;
|
||||||
|
assert_eq!(data[0], 0);
|
||||||
|
data[0] = 0x0e;
|
||||||
|
assert_eq!(data[0], 0x0e);
|
||||||
|
assert_eq!(data[MAX_PERMITTED_DATA_INCREASE - 1], 0);
|
||||||
|
data[MAX_PERMITTED_DATA_INCREASE - 1] = 0x0f;
|
||||||
|
assert_eq!(data[MAX_PERMITTED_DATA_INCREASE - 1], 0x0f);
|
||||||
|
for i in 1..20 {
|
||||||
|
data[i] = i as u8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -884,6 +884,8 @@ fn test_program_bpf_invoke_sanity() {
|
|||||||
invoked_program_id.clone(),
|
invoked_program_id.clone(),
|
||||||
invoked_program_id.clone(),
|
invoked_program_id.clone(),
|
||||||
invoked_program_id.clone(),
|
invoked_program_id.clone(),
|
||||||
|
invoked_program_id.clone(),
|
||||||
|
solana_sdk::system_program::id(),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
assert_eq!(invoked_programs.len(), expected_invoked_programs.len());
|
assert_eq!(invoked_programs.len(), expected_invoked_programs.len());
|
||||||
|
@ -20,7 +20,7 @@ use solana_sdk::{
|
|||||||
epoch_schedule::EpochSchedule,
|
epoch_schedule::EpochSchedule,
|
||||||
feature_set::{
|
feature_set::{
|
||||||
cpi_data_cost, cpi_share_ro_and_exec_accounts, demote_sysvar_write_locks,
|
cpi_data_cost, cpi_share_ro_and_exec_accounts, demote_sysvar_write_locks,
|
||||||
enforce_aligned_host_addrs, sysvar_via_syscall,
|
enforce_aligned_host_addrs, sysvar_via_syscall, update_data_on_realloc,
|
||||||
},
|
},
|
||||||
hash::{Hasher, HASH_BYTES},
|
hash::{Hasher, HASH_BYTES},
|
||||||
ic_msg,
|
ic_msg,
|
||||||
@ -1997,7 +1997,7 @@ fn call<'a>(
|
|||||||
let invoke_context = syscall.get_context()?;
|
let invoke_context = syscall.get_context()?;
|
||||||
for (i, (account, account_ref)) in accounts.iter().zip(account_refs).enumerate() {
|
for (i, (account, account_ref)) in accounts.iter().zip(account_refs).enumerate() {
|
||||||
let account = account.borrow();
|
let account = account.borrow();
|
||||||
if let Some(account_ref) = account_ref {
|
if let Some(mut account_ref) = account_ref {
|
||||||
if message.is_writable(i, demote_sysvar_write_locks) && !account.executable {
|
if message.is_writable(i, demote_sysvar_write_locks) && !account.executable {
|
||||||
*account_ref.lamports = account.lamports;
|
*account_ref.lamports = account.lamports;
|
||||||
*account_ref.owner = account.owner;
|
*account_ref.owner = account.owner;
|
||||||
@ -2027,12 +2027,22 @@ fn call<'a>(
|
|||||||
)
|
)
|
||||||
.into());
|
.into());
|
||||||
}
|
}
|
||||||
let _ = translate(
|
if invoke_context.is_feature_active(&update_data_on_realloc::id()) {
|
||||||
memory_mapping,
|
account_ref.data = translate_slice_mut::<u8>(
|
||||||
AccessType::Store,
|
memory_mapping,
|
||||||
account_ref.vm_data_addr,
|
account_ref.vm_data_addr,
|
||||||
account.data().len() as u64,
|
account.data().len() as u64,
|
||||||
)?;
|
&bpf_loader_deprecated::id(), // Don't care since it is byte aligned
|
||||||
|
true,
|
||||||
|
)?;
|
||||||
|
} else {
|
||||||
|
let _ = translate(
|
||||||
|
memory_mapping,
|
||||||
|
AccessType::Store,
|
||||||
|
account_ref.vm_data_addr,
|
||||||
|
account.data().len() as u64,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
*account_ref.ref_to_len_in_vm = account.data().len() as u64;
|
*account_ref.ref_to_len_in_vm = account.data().len() as u64;
|
||||||
*account_ref.serialized_len_ptr = account.data().len() as u64;
|
*account_ref.serialized_len_ptr = account.data().len() as u64;
|
||||||
}
|
}
|
||||||
|
@ -127,6 +127,10 @@ pub mod enforce_aligned_host_addrs {
|
|||||||
solana_sdk::declare_id!("6Qob9Z4RwGdf599FDVCqsjuKjR8ZFR3oVs2ByRLWBsua");
|
solana_sdk::declare_id!("6Qob9Z4RwGdf599FDVCqsjuKjR8ZFR3oVs2ByRLWBsua");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub mod update_data_on_realloc {
|
||||||
|
solana_sdk::declare_id!("BkPcYCrwHXBoTsv9vMhiRF9gteZmDj3Uwisz9CDjoMKp");
|
||||||
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
/// Map of feature identifiers to user-visible description
|
/// Map of feature identifiers to user-visible description
|
||||||
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
|
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
|
||||||
@ -159,6 +163,7 @@ lazy_static! {
|
|||||||
(sysvar_via_syscall::id(), "provide sysvars via syscalls"),
|
(sysvar_via_syscall::id(), "provide sysvars via syscalls"),
|
||||||
(check_duplicates_by_hash::id(), "use transaction message hash for duplicate check"),
|
(check_duplicates_by_hash::id(), "use transaction message hash for duplicate check"),
|
||||||
(enforce_aligned_host_addrs::id(), "enforce aligned host addresses"),
|
(enforce_aligned_host_addrs::id(), "enforce aligned host addresses"),
|
||||||
|
(update_data_on_realloc::id(), "Retain updated data values modified after realloc via CPI"),
|
||||||
/*************** ADD NEW FEATURES HERE ***************/
|
/*************** ADD NEW FEATURES HERE ***************/
|
||||||
]
|
]
|
||||||
.iter()
|
.iter()
|
||||||
|
Reference in New Issue
Block a user