-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Return error if Transaction contains writable executable or ProgramData accounts #19629
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
runtime/src/accounts.rs
Outdated
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be more efficient to first check the books and then deserialize?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
runtime/src/accounts.rs
Outdated
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
InvalidAccountIndex
error 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