Add extra checks to verify_and_update (bp #13848) (#13849)

* Add extra checks to verify_and_update (#13848)

* Add extra checks to verify_and_update

* nudge

(cherry picked from commit ce4304cc9a)

# Conflicts:
#	runtime/src/message_processor.rs

* fix conflicts

Co-authored-by: Jack May <jack@solana.com>
This commit is contained in:
mergify[bot]
2020-11-29 11:27:30 +00:00
committed by GitHub
parent 51e8872804
commit ab235b8160

View File

@ -619,28 +619,31 @@ impl MessageProcessor {
// Verify the per-account instruction results // Verify the per-account instruction results
let (mut pre_sum, mut post_sum) = (0_u128, 0_u128); let (mut pre_sum, mut post_sum) = (0_u128, 0_u128);
let mut work = |_unique_index: usize, account_index: usize| { let mut work = |_unique_index: usize, account_index: usize| {
let key = &message.account_keys[account_index]; if account_index < message.account_keys.len() && account_index < accounts.len() {
let account = &accounts[account_index]; let key = &message.account_keys[account_index];
// Find the matching PreAccount let account = &accounts[account_index];
for pre_account in pre_accounts.iter_mut() { // Find the matching PreAccount
if *key == pre_account.key() { for pre_account in pre_accounts.iter_mut() {
// Verify account has no outstanding references and take one if *key == pre_account.key() {
let account = account // Verify account has no outstanding references and take one
.try_borrow_mut() let account = account
.map_err(|_| InstructionError::AccountBorrowOutstanding)?; .try_borrow_mut()
.map_err(|_| InstructionError::AccountBorrowOutstanding)?;
pre_account.verify(&program_id, &rent, &account)?; pre_account.verify(&program_id, &rent, &account)?;
pre_sum += u128::from(pre_account.lamports()); pre_sum += u128::from(pre_account.lamports());
post_sum += u128::from(account.lamports); post_sum += u128::from(account.lamports);
pre_account.update(&account); pre_account.update(&account);
return Ok(()); return Ok(());
}
} }
} }
Err(InstructionError::MissingAccount) Err(InstructionError::MissingAccount)
}; };
instruction.visit_each_account(&mut work)?; instruction.visit_each_account(&mut work)?;
work(0, instruction.program_id_index as usize)?;
// Verify that the total sum of all the lamports did not change // Verify that the total sum of all the lamports did not change
if pre_sum != post_sum { if pre_sum != post_sum {
@ -753,6 +756,7 @@ mod tests {
message::Message, message::Message,
native_loader::create_loadable_account, native_loader::create_loadable_account,
}; };
use std::iter::FromIterator;
#[test] #[test]
fn test_invoke_context() { fn test_invoke_context() {
@ -776,6 +780,11 @@ mod tests {
true, true,
)) ))
} }
let account = Account::new(1, 1, &solana_sdk::pubkey::Pubkey::default());
for program_id in program_ids.iter() {
pre_accounts.push(PreAccount::new(program_id, &account.clone(), false, true));
}
let mut invoke_context = ThisInvokeContext::new( let mut invoke_context = ThisInvokeContext::new(
&program_ids[0], &program_ids[0],
Rent::default(), Rent::default(),
@ -813,12 +822,15 @@ mod tests {
// modify account owned by the program // modify account owned by the program
accounts[owned_index].borrow_mut().data[0] = (MAX_DEPTH + owned_index) as u8; accounts[owned_index].borrow_mut().data[0] = (MAX_DEPTH + owned_index) as u8;
let mut these_accounts =
Vec::from_iter(accounts[not_owned_index..owned_index + 1].iter().cloned());
these_accounts.push(Rc::new(RefCell::new(Account::new(
1,
1,
&solana_sdk::pubkey::Pubkey::default(),
))));
invoke_context invoke_context
.verify_and_update( .verify_and_update(&message, &message.instructions[0], &these_accounts)
&message,
&message.instructions[0],
&accounts[not_owned_index..owned_index + 1],
)
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
invoke_context.pre_accounts[owned_index].data[0], invoke_context.pre_accounts[owned_index].data[0],
@ -1589,7 +1601,9 @@ mod tests {
let mut program_account = Account::new(1, 0, &native_loader::id()); let mut program_account = Account::new(1, 0, &native_loader::id());
program_account.executable = true; program_account.executable = true;
let executable_accounts = vec![(callee_program_id, RefCell::new(program_account))]; let executable_preaccount =
PreAccount::new(&callee_program_id, &program_account, false, true);
let executable_accounts = vec![(callee_program_id, RefCell::new(program_account.clone()))];
let owned_key = solana_sdk::pubkey::new_rand(); let owned_key = solana_sdk::pubkey::new_rand();
let owned_account = Account::new(42, 1, &callee_program_id); let owned_account = Account::new(42, 1, &callee_program_id);
@ -1603,11 +1617,16 @@ mod tests {
let mut accounts = vec![ let mut accounts = vec![
Rc::new(RefCell::new(owned_account)), Rc::new(RefCell::new(owned_account)),
Rc::new(RefCell::new(not_owned_account)), Rc::new(RefCell::new(not_owned_account)),
Rc::new(RefCell::new(program_account)),
]; ];
let mut invoke_context = ThisInvokeContext::new( let mut invoke_context = ThisInvokeContext::new(
&caller_program_id, &caller_program_id,
Rent::default(), Rent::default(),
vec![owned_preaccount, not_owned_preaccount], vec![
owned_preaccount,
not_owned_preaccount,
executable_preaccount,
],
vec![], vec![],
None, None,
ComputeBudget::default(), ComputeBudget::default(),