Skip to content
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

Reject faked stake/vote accounts in stake mgmt. #13615

Merged
merged 2 commits into from
Nov 16, 2020

Conversation

ryoqun
Copy link
Member

@ryoqun ryoqun commented Nov 16, 2020

Problem

There is no account.owner check for referenced stake/vote accounts when delegating/splitting/merging stake accounts.

Because these referenced accounts are read-only, the runtime doesn't enforce the account.owner check. Users can pass any accounts of any owner as long as it deserializes into StakeState or VoteState, so we must check account.owner by ourselves.

This time I checked this trait for possible similar issues, but I found other uses of KeyedAccount without owner check is legitimate:

impl StakeState {
pub fn get_rent_exempt_reserve(rent: &Rent) -> u64 {
rent.minimum_balance(std::mem::size_of::<StakeState>())
}
// utility function, used by Stakes, tests
pub fn from(account: &Account) -> Option<StakeState> {
account.state().ok()
}
pub fn stake_from(account: &Account) -> Option<Stake> {
Self::from(account).and_then(|state: Self| state.stake())
}
pub fn stake(&self) -> Option<Stake> {
match self {
StakeState::Stake(_meta, stake) => Some(*stake),
_ => None,
}
}
pub fn delegation_from(account: &Account) -> Option<Delegation> {
Self::from(account).and_then(|state: Self| state.delegation())
}
pub fn delegation(&self) -> Option<Delegation> {
match self {
StakeState::Stake(_meta, stake) => Some(stake.delegation),
_ => None,
}
}
pub fn authorized_from(account: &Account) -> Option<Authorized> {
Self::from(account).and_then(|state: Self| state.authorized())
}
pub fn authorized(&self) -> Option<Authorized> {
match self {
StakeState::Stake(meta, _stake) => Some(meta.authorized),
StakeState::Initialized(meta) => Some(meta.authorized),
_ => None,
}
}
pub fn lockup_from(account: &Account) -> Option<Lockup> {
Self::from(account).and_then(|state: Self| state.lockup())
}
pub fn lockup(&self) -> Option<Lockup> {
match self {
StakeState::Stake(meta, _stake) => Some(meta.lockup),
StakeState::Initialized(meta) => Some(meta.lockup),
_ => None,
}
}
}

Summary of Changes

Add guards and outright reject such transactions.

Also, this is feature-gated under stake_program_v2, implicitly.

Fixes #

@ryoqun
Copy link
Member Author

ryoqun commented Nov 16, 2020

@CriesofCarrots Could you review this before #13461 ?

@rwalker-com Hi, could you review this?

CriesofCarrots
CriesofCarrots previously approved these changes Nov 16, 2020
Copy link
Contributor

@CriesofCarrots CriesofCarrots left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix and process tests lgtm!
One nit to make stake_instruction test changes more clear.

programs/stake/src/stake_instruction.rs Outdated Show resolved Hide resolved
programs/stake/src/stake_instruction.rs Outdated Show resolved Hide resolved
Comment on lines +824 to +826
if vote_account.owner()? != solana_vote_program::id() {
return Err(InstructionError::IncorrectProgramId);
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jackcmay just making sure; it seems that IncorrectProgramId isn't used much; but I think this is a perfect usecase of IncorrectProgramId for these kinds of checks, I guess.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The description of this error is doesn't make much sense but the way you propose to use it here makes as much sense as any ;-)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fwiw, this seems perfectly consistent with how the error is used in the Vest program

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I copied from that. :)

@mergify mergify bot dismissed CriesofCarrots’s stale review November 16, 2020 18:33

Pull request has been modified.

Copy link
Contributor

@rwalker-com rwalker-com left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@ryoqun
Copy link
Member Author

ryoqun commented Nov 16, 2020

@CriesofCarrots @rob-solana Thanks for reviewing! I'm going to merge this shortly after now. I'm doing last-minute local test this.

@ryoqun
Copy link
Member Author

ryoqun commented Nov 16, 2020

buildkite/solana/downstream-projects — Failed (exit status 101)

Merging this despite the quoted build failure; I'm aware this is already being addressed and the failure isn't related to this pr.

@ryoqun ryoqun merged commit 2b3faa1 into solana-labs:master Nov 16, 2020
mergify bot pushed a commit that referenced this pull request Nov 16, 2020
* Reject faked stake/vote accounts in stake mgmt.

* Use clearer name

(cherry picked from commit 2b3faa1)

# Conflicts:
#	programs/stake/src/stake_instruction.rs
mergify bot pushed a commit that referenced this pull request Nov 16, 2020
* Reject faked stake/vote accounts in stake mgmt.

* Use clearer name

(cherry picked from commit 2b3faa1)
CriesofCarrots pushed a commit that referenced this pull request Nov 16, 2020
* Reject faked stake/vote accounts in stake mgmt.

* Use clearer name

(cherry picked from commit 2b3faa1)
mergify bot added a commit that referenced this pull request Nov 16, 2020
* Reject faked stake/vote accounts in stake mgmt. (#13615)

* Reject faked stake/vote accounts in stake mgmt.

* Use clearer name

(cherry picked from commit 2b3faa1)

# Conflicts:
#	programs/stake/src/stake_instruction.rs

* Fix conflict

Co-authored-by: Ryo Onodera <ryoqun@gmail.com>
mergify bot added a commit that referenced this pull request Nov 16, 2020
* Reject faked stake/vote accounts in stake mgmt.

* Use clearer name

(cherry picked from commit 2b3faa1)

Co-authored-by: Ryo Onodera <ryoqun@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants