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
22 changes: 8 additions & 14 deletions ledger-tool/src/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,13 +409,7 @@ pub fn program(ledger_path: &Path, matches: &ArgMatches<'_>) {
pubkey,
AccountSharedData::new(0, allocation_size, &Pubkey::new_unique()),
));
instruction_accounts.push(InstructionAccount {
index_in_transaction: 0,
index_in_caller: 0,
index_in_callee: 0,
is_signer: false,
is_writable: true,
});
instruction_accounts.push(InstructionAccount::new(0, 0, 0, false, true));
vec![]
}
Err(_) => {
Expand Down Expand Up @@ -486,13 +480,13 @@ pub fn program(ledger_path: &Path, matches: &ArgMatches<'_>) {
transaction_accounts.push((pubkey, account));
idx
};
InstructionAccount {
index_in_transaction: txn_acct_index as IndexOfAccount,
index_in_caller: txn_acct_index as IndexOfAccount,
index_in_callee: txn_acct_index as IndexOfAccount,
is_signer: account_info.is_signer.unwrap_or(false),
is_writable: account_info.is_writable.unwrap_or(false),
}
InstructionAccount::new(
txn_acct_index as IndexOfAccount,
txn_acct_index as IndexOfAccount,
txn_acct_index as IndexOfAccount,
account_info.is_signer.unwrap_or(false),
account_info.is_writable.unwrap_or(false),
)
})
.collect();
input.instruction_data
Expand Down
116 changes: 56 additions & 60 deletions program-runtime/src/invoke_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,8 +357,10 @@ impl<'a> InvokeContext<'a> {
let instruction_account = deduplicated_instruction_accounts
.get_mut(duplicate_index)
.ok_or(InstructionError::NotEnoughAccountKeys)?;
instruction_account.is_signer |= account_meta.is_signer;
instruction_account.is_writable |= account_meta.is_writable;
instruction_account
.set_is_signer(instruction_account.is_signer() || account_meta.is_signer);
instruction_account
.set_is_writable(instruction_account.is_writable() || account_meta.is_writable);
} else {
let index_in_caller = instruction_context
.find_index_of_instruction_account(
Expand All @@ -374,13 +376,13 @@ impl<'a> InvokeContext<'a> {
InstructionError::MissingAccount
})?;
duplicate_indicies.push(deduplicated_instruction_accounts.len());
deduplicated_instruction_accounts.push(InstructionAccount {
deduplicated_instruction_accounts.push(InstructionAccount::new(
index_in_transaction,
index_in_caller,
index_in_callee: instruction_account_index as IndexOfAccount,
is_signer: account_meta.is_signer,
is_writable: account_meta.is_writable,
});
instruction_account_index as IndexOfAccount,
account_meta.is_signer,
account_meta.is_writable,
));
}
}
for instruction_account in deduplicated_instruction_accounts.iter() {
Expand All @@ -390,7 +392,7 @@ impl<'a> InvokeContext<'a> {
)?;

// Readonly in caller cannot become writable in callee
if instruction_account.is_writable && !borrowed_account.is_writable() {
if instruction_account.is_writable() && !borrowed_account.is_writable() {
ic_msg!(
self,
"{}'s writable privilege escalated",
Expand All @@ -401,7 +403,7 @@ impl<'a> InvokeContext<'a> {

// To be signed in the callee,
// it must be either signed in the caller or by the program
if instruction_account.is_signer
if instruction_account.is_signer()
&& !(borrowed_account.is_signer() || signers.contains(borrowed_account.get_key()))
{
ic_msg!(
Expand Down Expand Up @@ -838,13 +840,13 @@ pub fn mock_process_instruction_with_feature_set<
instruction_account.index_in_transaction == index_in_transaction
})
.unwrap_or(instruction_account_index) as IndexOfAccount;
instruction_accounts.push(InstructionAccount {
instruction_accounts.push(InstructionAccount::new(
index_in_transaction,
index_in_transaction,
index_in_caller: index_in_transaction,
index_in_callee,
is_signer: account_meta.is_signer,
is_writable: account_meta.is_writable,
});
account_meta.is_signer,
account_meta.is_writable,
));
}
if program_indices.is_empty() {
program_indices.insert(0, transaction_accounts.len() as IndexOfAccount);
Expand Down Expand Up @@ -959,12 +961,14 @@ mod tests {
let instruction_data = instruction_context.get_instruction_data();
let program_id = instruction_context.get_last_program_key(transaction_context)?;
let instruction_accounts = (0..4)
.map(|instruction_account_index| InstructionAccount {
index_in_transaction: instruction_account_index,
index_in_caller: instruction_account_index,
index_in_callee: instruction_account_index,
is_signer: false,
is_writable: false,
.map(|instruction_account_index| {
InstructionAccount::new(
instruction_account_index,
instruction_account_index,
instruction_account_index,
false,
false,
)
})
.collect::<Vec<_>>();
assert_eq!(
Expand Down Expand Up @@ -1064,26 +1068,26 @@ mod tests {
solana_pubkey::new_rand(),
AccountSharedData::new(index as u64, 1, invoke_stack.get(index).unwrap()),
));
instruction_accounts.push(InstructionAccount {
index_in_transaction: index as IndexOfAccount,
index_in_caller: index as IndexOfAccount,
index_in_callee: instruction_accounts.len() as IndexOfAccount,
is_signer: false,
is_writable: true,
});
instruction_accounts.push(InstructionAccount::new(
index as IndexOfAccount,
index as IndexOfAccount,
instruction_accounts.len() as IndexOfAccount,
false,
true,
));
}
for (index, program_id) in invoke_stack.iter().enumerate() {
transaction_accounts.push((
*program_id,
AccountSharedData::new(1, 1, &solana_pubkey::Pubkey::default()),
));
instruction_accounts.push(InstructionAccount {
index_in_transaction: index as IndexOfAccount,
index_in_caller: index as IndexOfAccount,
index_in_callee: index as IndexOfAccount,
is_signer: false,
is_writable: false,
});
instruction_accounts.push(InstructionAccount::new(
index as IndexOfAccount,
index as IndexOfAccount,
index as IndexOfAccount,
false,
false,
));
}
with_mock_invoke_context!(invoke_context, transaction_context, transaction_accounts);

Expand Down Expand Up @@ -1154,12 +1158,14 @@ mod tests {
AccountMeta::new_readonly(transaction_accounts.get(2).unwrap().0, false),
];
let instruction_accounts = (0..4)
.map(|instruction_account_index| InstructionAccount {
index_in_transaction: instruction_account_index,
index_in_caller: instruction_account_index,
index_in_callee: instruction_account_index,
is_signer: false,
is_writable: instruction_account_index < 2,
.map(|instruction_account_index| {
InstructionAccount::new(
instruction_account_index,
instruction_account_index,
instruction_account_index,
false,
instruction_account_index < 2,
)
})
.collect::<Vec<_>>();
with_mock_invoke_context!(invoke_context, transaction_context, transaction_accounts);
Expand Down Expand Up @@ -1210,12 +1216,14 @@ mod tests {
AccountMeta::new_readonly(transaction_accounts.get(2).unwrap().0, false),
];
let instruction_accounts = (0..4)
.map(|instruction_account_index| InstructionAccount {
index_in_transaction: instruction_account_index,
index_in_caller: instruction_account_index,
index_in_callee: instruction_account_index,
is_signer: false,
is_writable: instruction_account_index < 2,
.map(|instruction_account_index| {
InstructionAccount::new(
instruction_account_index,
instruction_account_index,
instruction_account_index,
false,
instruction_account_index < 2,
)
})
.collect::<Vec<_>>();
with_mock_invoke_context!(invoke_context, transaction_context, transaction_accounts);
Expand Down Expand Up @@ -1307,20 +1315,8 @@ mod tests {
(program_key, program_account),
];
let instruction_accounts = [
InstructionAccount {
index_in_transaction: 0,
index_in_caller: 0,
index_in_callee: 0,
is_signer: false,
is_writable: true,
},
InstructionAccount {
index_in_transaction: 1,
index_in_caller: 1,
index_in_callee: 1,
is_signer: false,
is_writable: false,
},
InstructionAccount::new(0, 0, 0, false, true),
InstructionAccount::new(1, 1, 1, false, false),
];
with_mock_invoke_context!(invoke_context, transaction_context, transaction_accounts);
let mut program_cache_for_tx_batch = ProgramCacheForTxBatch::default();
Expand Down
14 changes: 7 additions & 7 deletions program-runtime/src/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -628,13 +628,13 @@ mod tests {
.iter()
.position(|account_index| account_index == index_in_transaction)
.unwrap_or(index_in_instruction);
InstructionAccount {
index_in_transaction: *index_in_transaction,
index_in_caller: *index_in_transaction,
index_in_callee: index_in_callee as IndexOfAccount,
is_signer: false,
is_writable: is_writable(index_in_instruction),
}
InstructionAccount::new(
*index_in_transaction,
*index_in_transaction,
index_in_callee as IndexOfAccount,
false,
is_writable(index_in_instruction),
)
})
.collect()
}
Expand Down
2 changes: 1 addition & 1 deletion program-test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ impl solana_sysvar::program_stubs::SyscallStubs for SyscallStubs {
.set_owner(account_info.owner.as_ref())
.unwrap();
}
if instruction_account.is_writable {
if instruction_account.is_writable() {
account_indices.push((instruction_account.index_in_caller, account_info_index));
}
}
Expand Down
10 changes: 5 additions & 5 deletions programs/bpf_loader/benches/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,13 @@ fn create_inputs(owner: Pubkey, num_instruction_accounts: usize) -> TransactionC
.iter()
.position(|account| account.index_in_transaction == index_in_transaction)
.unwrap_or(instruction_account_index) as IndexOfAccount;
instruction_accounts.push(InstructionAccount {
index_in_caller: instruction_account_index as IndexOfAccount,
instruction_accounts.push(InstructionAccount::new(
instruction_account_index as IndexOfAccount,
index_in_transaction,
index_in_callee,
is_signer: false,
is_writable: instruction_account_index >= 4,
});
false,
instruction_account_index >= 4,
));
}

let mut transaction_context =
Expand Down
38 changes: 13 additions & 25 deletions programs/bpf_loader/src/syscalls/cpi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -875,8 +875,8 @@ where
accounts.push(TranslatedAccount {
index_in_caller: instruction_account.index_in_caller,
caller_account,
update_caller_account_region: instruction_account.is_writable || update_caller,
update_caller_account_info: instruction_account.is_writable,
update_caller_account_region: instruction_account.is_writable() || update_caller,
update_caller_account_info: instruction_account.is_writable(),
});
} else {
ic_msg!(
Expand Down Expand Up @@ -1324,15 +1324,15 @@ mod tests {
let instruction_accounts = $instruction_accounts
.iter()
.enumerate()
.map(
|(index_in_callee, index_in_transaction)| InstructionAccount {
index_in_transaction: *index_in_transaction as IndexOfAccount,
index_in_caller: *index_in_transaction as IndexOfAccount,
index_in_callee: index_in_callee as IndexOfAccount,
is_signer: false,
is_writable: $transaction_accounts[*index_in_transaction as usize].2,
},
)
.map(|(index_in_callee, index_in_transaction)| {
InstructionAccount::new(
*index_in_transaction as IndexOfAccount,
*index_in_transaction as IndexOfAccount,
index_in_callee as IndexOfAccount,
false,
$transaction_accounts[*index_in_transaction as usize].2,
)
})
.collect::<Vec<_>>();
let transaction_accounts = $transaction_accounts
.into_iter()
Expand Down Expand Up @@ -1879,20 +1879,8 @@ mod tests {

let accounts = SyscallInvokeSignedRust::translate_accounts(
&[
InstructionAccount {
index_in_transaction: 1,
index_in_caller: 0,
index_in_callee: 0,
is_signer: false,
is_writable: true,
},
InstructionAccount {
index_in_transaction: 1,
index_in_caller: 0,
index_in_callee: 0,
is_signer: false,
is_writable: true,
},
InstructionAccount::new(1, 0, 0, false, true),
InstructionAccount::new(1, 0, 0, false, true),
],
vm_addr,
1,
Expand Down
14 changes: 7 additions & 7 deletions programs/bpf_loader/src/syscalls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4438,13 +4438,13 @@ mod tests {
.transaction_context
.get_instruction_context_stack_height()
{
let instruction_accounts = [InstructionAccount {
index_in_transaction: index_in_trace.saturating_add(1) as IndexOfAccount,
index_in_caller: 0, // This is incorrect / inconsistent but not required
index_in_callee: 0,
is_signer: false,
is_writable: false,
}];
let instruction_accounts = [InstructionAccount::new(
index_in_trace.saturating_add(1) as IndexOfAccount,
0, // This is incorrect / inconsistent but not required
0,
false,
false,
)];
invoke_context
.transaction_context
.get_next_instruction_context()
Expand Down
8 changes: 1 addition & 7 deletions programs/sbf/benches/bpf_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,7 @@ macro_rules! with_mock_invoke_context {
AccountSharedData::new(2, $account_size, &program_key),
),
];
let instruction_accounts = vec![InstructionAccount {
index_in_transaction: 2,
index_in_caller: 2,
index_in_callee: 0,
is_signer: false,
is_writable: true,
}];
let instruction_accounts = vec![InstructionAccount::new(2, 2, 0, false, true)];
solana_program_runtime::with_mock_invoke_context!(
$invoke_context,
transaction_context,
Expand Down
16 changes: 2 additions & 14 deletions programs/system/src/system_instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,20 +294,8 @@ mod test {
(system_program::id(), AccountSharedData::default()),
];
let $instruction_accounts = vec![
InstructionAccount {
index_in_transaction: 0,
index_in_caller: 0,
index_in_callee: 0,
is_signer: true,
is_writable: true,
},
InstructionAccount {
index_in_transaction: 1,
index_in_caller: 1,
index_in_callee: 1,
is_signer: false,
is_writable: true,
},
InstructionAccount::new(0, 0, 0, true, true),
InstructionAccount::new(1, 1, 1, false, true),
];
with_mock_invoke_context!($invoke_context, transaction_context, transaction_accounts);
};
Expand Down
Loading
Loading