Skip to content
This repository has been archived by the owner on Jan 13, 2025. It is now read-only.

Commit

Permalink
Cap number of program address seeds (#13925)
Browse files Browse the repository at this point in the history
* Cap number of program address seeds

* fmt

Co-authored-by: Michael Vines <mvines@gmail.com>
  • Loading branch information
jackcmay and mvines authored Dec 2, 2020
1 parent 4431589 commit e6f54ff
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 8 deletions.
15 changes: 11 additions & 4 deletions programs/bpf_loader/src/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use solana_sdk::{
message::Message,
process_instruction::{stable_log, ComputeMeter, InvokeContext, Logger},
program_error::ProgramError,
pubkey::{Pubkey, PubkeyError},
pubkey::{Pubkey, PubkeyError, MAX_SEEDS},
};
use std::{
alloc::Layout,
Expand Down Expand Up @@ -534,6 +534,9 @@ impl<'a> SyscallObject<BPFError> for SyscallCreateProgramAddress<'a> {
// TODO need ref?
let untranslated_seeds =
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
.iter()
.map(|untranslated_seed| {
Expand All @@ -548,9 +551,7 @@ impl<'a> SyscallObject<BPFError> for SyscallCreateProgramAddress<'a> {
.collect::<Result<Vec<_>, EbpfError<BPFError>>>()?;
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)
.map_err(SyscallError::BadSeeds)
{
let new_address = match Pubkey::create_program_address(&seeds, program_id) {
Ok(address) => address,
Err(_) => return Ok(1),
};
Expand Down Expand Up @@ -828,6 +829,9 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedRust<'a> {
ro_regions,
self.loader_id
)?;
if signers_seeds.len() > MAX_SEEDS {
return Err(SyscallError::BadSeeds(PubkeyError::MaxSeedLengthExceeded).into());
}
for signer_seeds in signers_seeds.iter() {
let untranslated_seeds = translate_slice!(
&[u8],
Expand Down Expand Up @@ -1081,6 +1085,9 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedC<'a> {
ro_regions,
self.loader_id
)?;
if signers_seeds.len() > MAX_SEEDS {
return Err(SyscallError::BadSeeds(PubkeyError::MaxSeedLengthExceeded).into());
}
Ok(signers_seeds
.iter()
.map(|signer_seeds| {
Expand Down
16 changes: 12 additions & 4 deletions sdk/program/src/pubkey.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ use num_derive::{FromPrimitive, ToPrimitive};
use std::{convert::TryFrom, fmt, mem, str::FromStr};
use thiserror::Error;

/// maximum length of derived pubkey seed
/// maximum length of derived `Pubkey` seed
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)]
pub enum PubkeyError {
Expand Down Expand Up @@ -136,15 +138,21 @@ impl Pubkey {
seeds: &[&[u8]],
program_id: &Pubkey,
) -> 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
// not supported
#[cfg(not(target_arch = "bpf"))]
{
let mut hasher = crate::hash::Hasher::default();
for seed in seeds.iter() {
if seed.len() > MAX_SEED_LEN {
return Err(PubkeyError::MaxSeedLengthExceeded);
}
hasher.hash(seed);
}
hasher.hashv(&[program_id.as_ref(), "ProgramDerivedAddress".as_ref()]);
Expand Down

0 comments on commit e6f54ff

Please sign in to comment.