Skip to content

Commit

Permalink
put limit on account data length (solana-labs#7320)
Browse files Browse the repository at this point in the history
* put limit on account data length

* proper debug message
  • Loading branch information
ParthDesai authored Dec 10, 2019
1 parent 6d2861f commit 696cb29
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 2 deletions.
49 changes: 47 additions & 2 deletions runtime/src/system_instruction_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ use solana_sdk::system_instruction::{SystemError, SystemInstruction};
use solana_sdk::system_program;
use solana_sdk::sysvar;

// 10 MB
const MAX_PERMITTED_DATA_LENGTH: u64 = 10 * 1024 * 1024;

fn create_system_account(
from: &mut KeyedAccount,
to: &mut KeyedAccount,
lamports: u64,
space: u64,
data_length: u64,
program_id: &Pubkey,
) -> Result<(), InstructionError> {
// if lamports == 0, the from account isn't touched
Expand Down Expand Up @@ -50,10 +53,18 @@ fn create_system_account(
return Err(SystemError::ResultWithNegativeLamports.into());
}

if data_length > MAX_PERMITTED_DATA_LENGTH {
debug!(
"CreateAccount: requested data_length: {} is more than maximum allowed",
data_length
);
return Err(SystemError::InvalidAccountDataLength.into());
}

assign_account_to_program(to, program_id)?;
from.account.lamports -= lamports;
to.account.lamports += lamports;
to.account.data = vec![0; space as usize];
to.account.data = vec![0; data_length as usize];
to.account.executable = false;
Ok(())
}
Expand Down Expand Up @@ -236,6 +247,40 @@ mod tests {
assert_eq!(to_account, unchanged_account);
}

#[test]
fn test_request_more_than_allowed_data_length() {
let mut from_account = Account::new(100, 0, &system_program::id());
let from_account_key = Pubkey::new_rand();
let mut to_account = Account::default();
let to_account_key = Pubkey::new_rand();

// Trying to request more data length than permitted will result in failure
let result = create_system_account(
&mut KeyedAccount::new(&from_account_key, true, &mut from_account),
&mut KeyedAccount::new(&to_account_key, true, &mut to_account),
50,
MAX_PERMITTED_DATA_LENGTH + 1,
&system_program::id(),
);
assert!(result.is_err());
assert_eq!(
result.err().unwrap(),
SystemError::InvalidAccountDataLength.into()
);

// Trying to request equal or less data length than permitted will be successful
let result = create_system_account(
&mut KeyedAccount::new(&from_account_key, true, &mut from_account),
&mut KeyedAccount::new(&to_account_key, true, &mut to_account),
50,
MAX_PERMITTED_DATA_LENGTH,
&system_program::id(),
);
assert!(result.is_ok());
assert_eq!(to_account.lamports, 50);
assert_eq!(to_account.data.len() as u64, MAX_PERMITTED_DATA_LENGTH);
}

#[test]
fn test_create_already_in_use() {
// Attempt to create system account in account already owned by another program
Expand Down
1 change: 1 addition & 0 deletions sdk/src/system_instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub enum SystemError {
ResultWithNegativeLamports,
InvalidProgramId,
InvalidAccountId,
InvalidAccountDataLength,
}

impl<T> DecodeError<T> for SystemError {
Expand Down

0 comments on commit 696cb29

Please sign in to comment.