Cap number of program address seeds (#13925)
* Cap number of program address seeds * fmt Co-authored-by: Michael Vines <mvines@gmail.com>
This commit is contained in:
@ -23,7 +23,7 @@ use solana_sdk::{
|
|||||||
message::Message,
|
message::Message,
|
||||||
process_instruction::{stable_log, ComputeMeter, InvokeContext, Logger},
|
process_instruction::{stable_log, ComputeMeter, InvokeContext, Logger},
|
||||||
program_error::ProgramError,
|
program_error::ProgramError,
|
||||||
pubkey::{Pubkey, PubkeyError},
|
pubkey::{Pubkey, PubkeyError, MAX_SEEDS},
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
alloc::Layout,
|
alloc::Layout,
|
||||||
@ -534,6 +534,9 @@ impl<'a> SyscallObject<BPFError> for SyscallCreateProgramAddress<'a> {
|
|||||||
// TODO need ref?
|
// TODO need ref?
|
||||||
let untranslated_seeds =
|
let untranslated_seeds =
|
||||||
translate_slice!(&[&u8], seeds_addr, seeds_len, ro_regions, self.loader_id)?;
|
translate_slice!(&[&u8], seeds_addr, seeds_len, ro_regions, self.loader_id)?;
|
||||||
|
if untranslated_seeds.len() > MAX_SEEDS {
|
||||||
|
return Ok(1);
|
||||||
|
}
|
||||||
let seeds = untranslated_seeds
|
let seeds = untranslated_seeds
|
||||||
.iter()
|
.iter()
|
||||||
.map(|untranslated_seed| {
|
.map(|untranslated_seed| {
|
||||||
@ -548,9 +551,7 @@ impl<'a> SyscallObject<BPFError> for SyscallCreateProgramAddress<'a> {
|
|||||||
.collect::<Result<Vec<_>, EbpfError<BPFError>>>()?;
|
.collect::<Result<Vec<_>, EbpfError<BPFError>>>()?;
|
||||||
let program_id = translate_type!(Pubkey, program_id_addr, ro_regions, self.loader_id)?;
|
let program_id = translate_type!(Pubkey, program_id_addr, ro_regions, self.loader_id)?;
|
||||||
|
|
||||||
let new_address = match Pubkey::create_program_address(&seeds, program_id)
|
let new_address = match Pubkey::create_program_address(&seeds, program_id) {
|
||||||
.map_err(SyscallError::BadSeeds)
|
|
||||||
{
|
|
||||||
Ok(address) => address,
|
Ok(address) => address,
|
||||||
Err(_) => return Ok(1),
|
Err(_) => return Ok(1),
|
||||||
};
|
};
|
||||||
@ -828,6 +829,9 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedRust<'a> {
|
|||||||
ro_regions,
|
ro_regions,
|
||||||
self.loader_id
|
self.loader_id
|
||||||
)?;
|
)?;
|
||||||
|
if signers_seeds.len() > MAX_SEEDS {
|
||||||
|
return Err(SyscallError::BadSeeds(PubkeyError::MaxSeedLengthExceeded).into());
|
||||||
|
}
|
||||||
for signer_seeds in signers_seeds.iter() {
|
for signer_seeds in signers_seeds.iter() {
|
||||||
let untranslated_seeds = translate_slice!(
|
let untranslated_seeds = translate_slice!(
|
||||||
&[u8],
|
&[u8],
|
||||||
@ -1081,6 +1085,9 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedC<'a> {
|
|||||||
ro_regions,
|
ro_regions,
|
||||||
self.loader_id
|
self.loader_id
|
||||||
)?;
|
)?;
|
||||||
|
if signers_seeds.len() > MAX_SEEDS {
|
||||||
|
return Err(SyscallError::BadSeeds(PubkeyError::MaxSeedLengthExceeded).into());
|
||||||
|
}
|
||||||
Ok(signers_seeds
|
Ok(signers_seeds
|
||||||
.iter()
|
.iter()
|
||||||
.map(|signer_seeds| {
|
.map(|signer_seeds| {
|
||||||
|
@ -3,8 +3,10 @@ use num_derive::{FromPrimitive, ToPrimitive};
|
|||||||
use std::{convert::TryFrom, fmt, mem, str::FromStr};
|
use std::{convert::TryFrom, fmt, mem, str::FromStr};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
/// maximum length of derived pubkey seed
|
/// maximum length of derived `Pubkey` seed
|
||||||
pub const MAX_SEED_LEN: usize = 32;
|
pub const MAX_SEED_LEN: usize = 32;
|
||||||
|
/// Maximum number of seeds
|
||||||
|
pub const MAX_SEEDS: usize = 16;
|
||||||
|
|
||||||
#[derive(Error, Debug, Serialize, Clone, PartialEq, FromPrimitive, ToPrimitive)]
|
#[derive(Error, Debug, Serialize, Clone, PartialEq, FromPrimitive, ToPrimitive)]
|
||||||
pub enum PubkeyError {
|
pub enum PubkeyError {
|
||||||
@ -136,15 +138,21 @@ impl Pubkey {
|
|||||||
seeds: &[&[u8]],
|
seeds: &[&[u8]],
|
||||||
program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
) -> Result<Pubkey, PubkeyError> {
|
) -> Result<Pubkey, PubkeyError> {
|
||||||
|
if seeds.len() > MAX_SEEDS {
|
||||||
|
return Err(PubkeyError::MaxSeedLengthExceeded);
|
||||||
|
}
|
||||||
|
for seed in seeds.iter() {
|
||||||
|
if seed.len() > MAX_SEED_LEN {
|
||||||
|
return Err(PubkeyError::MaxSeedLengthExceeded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Perform the calculation inline, calling this from within a program is
|
// Perform the calculation inline, calling this from within a program is
|
||||||
// not supported
|
// not supported
|
||||||
#[cfg(not(target_arch = "bpf"))]
|
#[cfg(not(target_arch = "bpf"))]
|
||||||
{
|
{
|
||||||
let mut hasher = crate::hash::Hasher::default();
|
let mut hasher = crate::hash::Hasher::default();
|
||||||
for seed in seeds.iter() {
|
for seed in seeds.iter() {
|
||||||
if seed.len() > MAX_SEED_LEN {
|
|
||||||
return Err(PubkeyError::MaxSeedLengthExceeded);
|
|
||||||
}
|
|
||||||
hasher.hash(seed);
|
hasher.hash(seed);
|
||||||
}
|
}
|
||||||
hasher.hashv(&[program_id.as_ref(), "ProgramDerivedAddress".as_ref()]);
|
hasher.hashv(&[program_id.as_ref(), "ProgramDerivedAddress".as_ref()]);
|
||||||
|
Reference in New Issue
Block a user