Re-do rent collection check on rent-exempt account#11349
Re-do rent collection check on rent-exempt account#11349ryoqun merged 11 commits intosolana-labs:masterfrom
Conversation
|
automerge label removed due to a CI failure |
|
todo
|
90b8c1b to
2be9db9
Compare
|
@t-nelson Thanks for early-review. I think this pr is now ready for serious review to merge. :) |
| ## Actual processing of collecting rent | ||
|
|
||
| Rent is due for one epoch's worth of time, and accounts always have `Account::rent_epoch` of `current_epoch + 1`. | ||
| Rent is due for one epoch's worth of time, and accounts have `Account::rent_epoch` of `current_epoch` or `current_epoch + 1` depending on the rent regime. |
There was a problem hiding this comment.
@rwalker-apple Hi, I'm yet again tweaking the rent protocol a bit, mainly affected by this dos possibility: #11342. Could you review this in your free time?
| "data": bs58::encode(expected_data).into_string(), | ||
| "executable": false, | ||
| "rentEpoch": 1, | ||
| "rentEpoch": 0, |
There was a problem hiding this comment.
@CriesofCarrots @jstarry Strictly speaking, we're breaking some semantics (=~ compatibility) of our rpc api a bit here according to this new rule for rentEpoch: https://github.com/solana-labs/solana/pull/11349/files#r469691300.
It's an incompatible change, but the change is soooo subtle, I think. So, I believe there should be virtually no one relying on rentEpoch being the current epoch or the next for rent-exempt accounts in any-conceivable way for the bizarre usecases.
There was a problem hiding this comment.
Or, if you have something to come to mind in terms of various partner integartions, please let me know. :)
There was a problem hiding this comment.
@ryoqun agreed, very unlikely this will cause any issues. I highly doubt anyone is using rentEpoch right now
There was a problem hiding this comment.
I don't know of any integrations using rentEpoch; I'm comfortable with this breaking change.
| account.rent_epoch = self.epoch | ||
| + if !self.enable_old_behavior && exempt { | ||
| // Rent isn't collected for the next epoch | ||
| // Make sure to check exempt status later in curent epoch again | ||
| 0 | ||
| } else { | ||
| // Rent is collected for next epoch | ||
| 1 | ||
| }; |
There was a problem hiding this comment.
This is the crux of this pr. The rest are just supplemental.
Codecov Report
@@ Coverage Diff @@
## master #11349 +/- ##
=======================================
Coverage 81.8% 81.8%
=======================================
Files 327 327
Lines 75668 75701 +33
=======================================
+ Hits 61932 61960 +28
- Misses 13736 13741 +5 |
t-nelson
left a comment
There was a problem hiding this comment.
LGTM! Just one readability nit, should you choose
| sol_assert(accounts[ARGUMENT_INDEX].is_signer); | ||
| sol_assert(accounts[ARGUMENT_INDEX].is_writable); | ||
| sol_assert(accounts[ARGUMENT_INDEX].rent_epoch == 1); | ||
| sol_assert(accounts[ARGUMENT_INDEX].rent_epoch == 0); |
There was a problem hiding this comment.
@jackcmay Like the RPC land, this pr changes slightly changes the semantics of rent_epoch, which is exposed to programs as well. Are you aware of any programs strictly relying on the current semantics of rent_epoch?
|
Not that I know of
…On Thu, Aug 13, 2020 at 5:19 PM Ryo Onodera ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In programs/bpf/c/src/invoked/invoked.c
<#11349 (comment)>:
> @@ -36,7 +36,7 @@ extern uint64_t entrypoint(const uint8_t *input) {
sol_assert(accounts[ARGUMENT_INDEX].data_len == 100);
sol_assert(accounts[ARGUMENT_INDEX].is_signer);
sol_assert(accounts[ARGUMENT_INDEX].is_writable);
- sol_assert(accounts[ARGUMENT_INDEX].rent_epoch == 1);
+ sol_assert(accounts[ARGUMENT_INDEX].rent_epoch == 0);
@jackcmay <https://github.com/jackcmay> Like the RPC land
<https://github.com/solana-labs/solana/pull/11349/files#r469692568>, this
pr changes slightly changes the semantics of rent_epoch
<https://github.com/solana-labs/solana/pull/11349/files#r469691300>,
which is exposed to programs as well. Are you aware of any programs
strictly relying on the current semantics of rent_epoch?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#11349 (review)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AJSLY6Q5QQJUJCBAWT2WSC3SAR7KXANCNFSM4PTGTSPQ>
.
|
|
@t-nelson Thanks for re-approving! Now waiting for last-minute local testing by me and final say from @rwalker-com / @rwalker-apple (if any). |
|
lgtm |
* wip: re-do rent collection check on rent-exempt account * Let's see how the ci goes * Restore previous code * Well, almost all new changes are revertable * Update doc * Add test and gating * Fix tests * Fix tests, especially avoid to change abi... * Fix more tests... * Fix snapshot restore * Align to _new_ with better uninitialized detection (cherry picked from commit 23fa84b) # Conflicts: # core/src/rpc_subscriptions.rs # core/tests/bank_forks.rs # runtime/src/bank.rs
* wip: re-do rent collection check on rent-exempt account * Let's see how the ci goes * Restore previous code * Well, almost all new changes are revertable * Update doc * Add test and gating * Fix tests * Fix tests, especially avoid to change abi... * Fix more tests... * Fix snapshot restore * Align to _new_ with better uninitialized detection (cherry picked from commit 23fa84b) # Conflicts: # core/src/rpc_subscriptions.rs
This is done finally and merged this! |
* Re-do rent collection check on rent-exempt account (#11349) * wip: re-do rent collection check on rent-exempt account * Let's see how the ci goes * Restore previous code * Well, almost all new changes are revertable * Update doc * Add test and gating * Fix tests * Fix tests, especially avoid to change abi... * Fix more tests... * Fix snapshot restore * Align to _new_ with better uninitialized detection (cherry picked from commit 23fa84b) # Conflicts: # core/src/rpc_subscriptions.rs * Fix conflicts Co-authored-by: Ryo Onodera <ryoqun@gmail.com>
* Re-do rent collection check on rent-exempt account (#11349) * wip: re-do rent collection check on rent-exempt account * Let's see how the ci goes * Restore previous code * Well, almost all new changes are revertable * Update doc * Add test and gating * Fix tests * Fix tests, especially avoid to change abi... * Fix more tests... * Fix snapshot restore * Align to _new_ with better uninitialized detection (cherry picked from commit 23fa84b) # Conflicts: # core/src/rpc_subscriptions.rs # core/tests/bank_forks.rs # runtime/src/bank.rs * Fix conflicts * Add missing comment Co-authored-by: Ryo Onodera <ryoqun@gmail.com>
Problem
Once passed as a rent-exempt for this epoch, accounts can reside with a penny (= 1 lamport) for the duration of the epoch. This could be exploited to occupy huge amount of storage for accounts, leading to a DOS.
Summary of Changes
rent-collect again only on previously-rent-exempt accounts.
Alternatively, we can use the highest bit of the=> Well, it turns out the fix is pretty simple.account.rent_epoch? or introduce a new bit field? This would introduce abi breakage, though...With this fix in effect, attackers actually must leave enough lamports for 10 * 1024 * 1024-byte MAX_PERMITTED_DATA_LENGTH accounts (= roughly 0.2 SOL (a)) to avoid it from being reclaimed after becoming non-rent-exempt.
So, it costs 10M SOL to do 1-epoch 500TB account storage DOS (b):
, meaning we're safe now.
Fixes #11342