diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index 23b43b73fd1c97..27fe7c6458b8d2 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -89,6 +89,13 @@ impl PreAccount { return Err(InstructionError::ModifiedProgramId); } + if self.owner != post.owner + && (solana_sdk::native_loader::check_id(&post.owner) + || solana_sdk::sysvar::check_id(&post.owner)) + { + return Err(InstructionError::ModifiedProgramId); + } + // An account not assigned to the program cannot have its balance decrease. if *program_id != self.owner // line coverage used to get branch coverage && self.lamports > post.lamports diff --git a/runtime/src/system_instruction_processor.rs b/runtime/src/system_instruction_processor.rs index 9fa9f2a3aaf26f..4be1fed34b55e6 100644 --- a/runtime/src/system_instruction_processor.rs +++ b/runtime/src/system_instruction_processor.rs @@ -4,7 +4,7 @@ use solana_sdk::{ account_utils::StateMut, instruction::InstructionError, keyed_account::{from_keyed_account, get_signers, next_keyed_account, KeyedAccount}, - nonce, + native_loader, nonce, nonce_keyed_account::NonceKeyedAccount, process_instruction::InvokeContext, program_utils::limited_deserialize, @@ -102,8 +102,8 @@ fn assign( return Err(InstructionError::MissingRequiredSignature); } - // guard against sysvars being made - if sysvar::check_id(&owner) { + // guard against sysvars and native loader programs being made + if sysvar::check_id(&owner) || native_loader::check_id(&owner) { debug!("Assign: program id {} invalid", owner); return Err(SystemError::InvalidProgramId.into()); } @@ -913,6 +913,24 @@ mod tests { ); } + #[test] + fn test_assign_to_native_loader() { + let new_owner = native_loader::id(); + + let from = solana_sdk::pubkey::new_rand(); + let mut from_account = Account::new(100, 0, &system_program::id()); + + assert_eq!( + assign( + &mut from_account, + &from.into(), + &new_owner, + &[from].iter().cloned().collect::>(), + ), + Err(SystemError::InvalidProgramId.into()) + ); + } + #[test] fn test_process_bogus_instruction() { // Attempt to assign with no accounts