Return error if Transaction contains writable executable or ProgramData accounts#19629
Conversation
|
Last 3 commits look good so far! |
bcffe21 to
26184e8
Compare
26184e8 to
e6a1ea2
Compare
e6a1ea2 to
bb85c6b
Compare
|
Ready for final review! |
9321e88 to
b77314d
Compare
| return Err(TransactionError::InvalidProgramForExecution); | ||
| // If a ProgramData account is present, it should only be writable | ||
| // if the bpf_loader_upgradeable account is also present | ||
| if let Ok(UpgradeableLoaderState::ProgramData { .. }) = |
There was a problem hiding this comment.
Would it be more efficient to first check the books and then deserialize?
There was a problem hiding this comment.
Could we skip the deserialization altogether and disallow writes to any account owned by the upgradeable loader? The only time a program other than the upgradeable loader can write to one of these accounts is if they top up the lamports which doesn't seem useful anyways.
b77314d to
11224c1
Compare
11224c1 to
a9fdc52
Compare
| return Err(TransactionError::InvalidProgramForExecution); | ||
| // If a ProgramData account is present, it should only be writable | ||
| // if the bpf_loader_upgradeable account is also present | ||
| if let Ok(UpgradeableLoaderState::ProgramData { .. }) = |
There was a problem hiding this comment.
Could we skip the deserialization altogether and disallow writes to any account owned by the upgradeable loader? The only time a program other than the upgradeable loader can write to one of these accounts is if they top up the lamports which doesn't seem useful anyways.
|
Adding more lamports might be necessary when we add support for realloc... |
|
True, do you think the bpf loader program could be responsible for that? |
|
I think so, the current plan is continue funding the account via the buffer account, so realloc to larger ProgramData account would require a larger buffer account with a larger associated number of tokens |
|
I'm not clear, @jackcmay , are you saying the upgradeable-loader program need to be present to do that sort of realloc? |
|
In order for a program to be realloc'd larger, the ProgramData account's balance will have to increase in order to still be rent-exempt. The question was who/how transfers those lamports. The current plan is for the larger buffer account to ferry along those lamports which means the upgradeable loader will always exist for all program reallocs. aka, we can probably skip deserialization as Justin suggested. |
…sent; remove is_upgradeable_loader_present exception for all other executables
283554b to
9a5213e
Compare
Codecov Report
@@ Coverage Diff @@
## master #19629 +/- ##
========================================
Coverage 82.5% 82.5%
========================================
Files 468 468
Lines 131847 132036 +189
========================================
+ Hits 108774 109036 +262
+ Misses 23073 23000 -73 |
…ta accounts (#19629) * Return error if Transaction locks an executable as writable * Return error if a ProgramData account is writable but the upgradable loader isn't present * Remove unreachable clause * Fixup bpf tests * Review comments * Add new TransactionError * Disallow writes to any upgradeable-loader account when loader not present; remove is_upgradeable_loader_present exception for all other executables (cherry picked from commit 38bbb77) # Conflicts: # programs/bpf/tests/programs.rs # runtime/src/accounts.rs # runtime/src/bank.rs # sdk/src/transaction.rs # storage-proto/proto/transaction_by_addr.proto # storage-proto/src/convert.rs
…ta accounts (#19629) * Return error if Transaction locks an executable as writable * Return error if a ProgramData account is writable but the upgradable loader isn't present * Remove unreachable clause * Fixup bpf tests * Review comments * Add new TransactionError * Disallow writes to any upgradeable-loader account when loader not present; remove is_upgradeable_loader_present exception for all other executables (cherry picked from commit 38bbb77) # Conflicts: # programs/bpf/tests/programs.rs # runtime/src/accounts.rs # runtime/src/bank.rs # sdk/src/transaction.rs # storage-proto/proto/transaction_by_addr.proto # storage-proto/src/convert.rs
…ta accounts (backport #19629) (#19729) * Return error if Transaction contains writable executable or ProgramData accounts (#19629) * Return error if Transaction locks an executable as writable * Return error if a ProgramData account is writable but the upgradable loader isn't present * Remove unreachable clause * Fixup bpf tests * Review comments * Add new TransactionError * Disallow writes to any upgradeable-loader account when loader not present; remove is_upgradeable_loader_present exception for all other executables (cherry picked from commit 38bbb77) # Conflicts: # programs/bpf/tests/programs.rs # runtime/src/accounts.rs # runtime/src/bank.rs # sdk/src/transaction.rs # storage-proto/proto/transaction_by_addr.proto # storage-proto/src/convert.rs * Fix conflicts Co-authored-by: Tyera Eulberg <teulberg@gmail.com> Co-authored-by: Tyera Eulberg <tyera@solana.com>
…ta accounts (backport #19629) (#19730) * Return error if Transaction contains writable executable or ProgramData accounts (#19629) * Return error if Transaction locks an executable as writable * Return error if a ProgramData account is writable but the upgradable loader isn't present * Remove unreachable clause * Fixup bpf tests * Review comments * Add new TransactionError * Disallow writes to any upgradeable-loader account when loader not present; remove is_upgradeable_loader_present exception for all other executables (cherry picked from commit 38bbb77) # Conflicts: # programs/bpf/tests/programs.rs # runtime/src/accounts.rs # runtime/src/bank.rs # sdk/src/transaction.rs # storage-proto/proto/transaction_by_addr.proto # storage-proto/src/convert.rs * Fix conflicts Co-authored-by: Tyera Eulberg <teulberg@gmail.com> Co-authored-by: Tyera Eulberg <tyera@solana.com>
…ta accounts (solana-labs#19629) * Return error if Transaction locks an executable as writable * Return error if a ProgramData account is writable but the upgradable loader isn't present * Remove unreachable clause * Fixup bpf tests * Review comments * Add new TransactionError * Disallow writes to any upgradeable-loader account when loader not present; remove is_upgradeable_loader_present exception for all other executables
…rogramData accounts (solana-labs#19629)" This reverts commit 737475e.
Problem
Accounts marked executable can only be written to if being upgraded (ie. if the UpgradeableLoader is present in the transaction). As of #19593, we're demoting top-level program ids incorrectly marked as writable, but we can't detect other executables until the accounts are loaded.
Similarly, ProgramData accounts can only be written if the UpgradeableLoader is present in the transaction, but we can't identify these accounts until they are loaded.
Summary of Changes
Return
InvalidAccountIndexerror to fail these types of Transactions and release the write lock quickly. Open to creating a new error type, if this seems significant enough.Needs rebase on #19593
@jackcmay @jstarry , the last 3 commits are ready for review