Skip to content

Commit

Permalink
gate libsecp256k1 upgrade to v0.5.0
Browse files Browse the repository at this point in the history
  • Loading branch information
t-nelson authored and mergify[bot] committed Jul 15, 2021
1 parent 3a85b77 commit abe5a0a
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 12 deletions.
15 changes: 12 additions & 3 deletions programs/bpf_loader/src/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ use solana_sdk::{
epoch_schedule::EpochSchedule,
feature_set::{
blake3_syscall_enabled, cpi_data_cost, enforce_aligned_host_addrs,
keccak256_syscall_enabled, memory_ops_syscalls, secp256k1_recover_syscall_enabled,
sysvar_via_syscall, update_data_on_realloc,
keccak256_syscall_enabled, libsecp256k1_0_5_upgrade_enabled, memory_ops_syscalls,
secp256k1_recover_syscall_enabled, sysvar_via_syscall, update_data_on_realloc,
},
hash::{Hasher, HASH_BYTES},
ic_msg,
Expand Down Expand Up @@ -346,6 +346,8 @@ pub fn bind_syscall_context_objects<'a>(
cost: bpf_compute_budget.secp256k1_recover_cost,
compute_meter: invoke_context.get_compute_meter(),
loader_id,
libsecp256k1_0_5_upgrade_enabled: invoke_context
.is_feature_active(&libsecp256k1_0_5_upgrade_enabled::id()),
}),
);

Expand Down Expand Up @@ -1366,6 +1368,7 @@ pub struct SyscallSecp256k1Recover<'a> {
cost: u64,
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
loader_id: &'a Pubkey,
libsecp256k1_0_5_upgrade_enabled: bool,
}

impl<'a> SyscallObject<BpfError> for SyscallSecp256k1Recover<'a> {
Expand Down Expand Up @@ -1426,7 +1429,13 @@ impl<'a> SyscallObject<BpfError> for SyscallSecp256k1Recover<'a> {
return;
}
};
let signature = match libsecp256k1::Signature::parse_standard_slice(signature) {
let sig_parse_result = if self.libsecp256k1_0_5_upgrade_enabled {
libsecp256k1::Signature::parse_standard_slice(signature)
} else {
libsecp256k1::Signature::parse_overflowing_slice(signature)
};

let signature = match sig_parse_result {
Ok(sig) => sig,
Err(_) => {
*result = Ok(Secp256k1RecoverError::InvalidSignature.into());
Expand Down
1 change: 0 additions & 1 deletion sdk/program/src/secp256k1_recover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ pub fn secp256k1_recover(
.map_err(|_| Secp256k1RecoverError::InvalidRecoveryId)?;
let signature = libsecp256k1::Signature::parse_standard_slice(signature)
.map_err(|_| Secp256k1RecoverError::InvalidSignature)?;

let secp256k1_key = libsecp256k1::recover(&message, &signature, &recovery_id)
.map_err(|_| Secp256k1RecoverError::InvalidSignature)?;
Ok(Secp256k1Pubkey::new(&secp256k1_key.serialize()[1..65]))
Expand Down
21 changes: 15 additions & 6 deletions sdk/src/secp256k1_instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ pub fn construct_eth_pubkey(
pub fn verify_eth_addresses(
data: &[u8],
instruction_datas: &[&[u8]],
libsecp256k1_0_5_upgrade_enabled: bool,
) -> Result<(), Secp256k1Error> {
if data.is_empty() {
return Err(Secp256k1Error::InvalidInstructionDataSize);
Expand Down Expand Up @@ -133,10 +134,18 @@ pub fn verify_eth_addresses(
if sig_end >= signature_instruction.len() {
return Err(Secp256k1Error::InvalidSignature);
}
let signature = libsecp256k1::Signature::parse_standard_slice(
&signature_instruction[sig_start..sig_end],
)
.map_err(|_| Secp256k1Error::InvalidSignature)?;

let sig_parse_result = if libsecp256k1_0_5_upgrade_enabled {
libsecp256k1::Signature::parse_standard_slice(
&signature_instruction[sig_start..sig_end],
)
} else {
libsecp256k1::Signature::parse_overflowing_slice(
&signature_instruction[sig_start..sig_end],
)
};

let signature = sig_parse_result.map_err(|_| Secp256k1Error::InvalidSignature)?;

let recovery_id = libsecp256k1::RecoveryId::parse(signature_instruction[sig_end])
.map_err(|_| Secp256k1Error::InvalidRecoveryId)?;
Expand Down Expand Up @@ -206,7 +215,7 @@ pub mod test {
let writer = std::io::Cursor::new(&mut instruction_data[1..]);
bincode::serialize_into(writer, &offsets).unwrap();

verify_eth_addresses(&instruction_data, &[&[0u8; 100]])
verify_eth_addresses(&instruction_data, &[&[0u8; 100]], false)
}

#[test]
Expand All @@ -221,7 +230,7 @@ pub mod test {
instruction_data.truncate(instruction_data.len() - 1);

assert_eq!(
verify_eth_addresses(&instruction_data, &[&[0u8; 100]]),
verify_eth_addresses(&instruction_data, &[&[0u8; 100]], false),
Err(Secp256k1Error::InvalidInstructionDataSize)
);

Expand Down
8 changes: 6 additions & 2 deletions sdk/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ impl Transaction {
.collect()
}

pub fn verify_precompiles(&self, _libsecp256k1_0_5_upgrade_enabled: bool) -> Result<()> {
pub fn verify_precompiles(&self, libsecp256k1_0_5_upgrade_enabled: bool) -> Result<()> {
for instruction in &self.message().instructions {
// The Transaction may not be sanitized at this point
if instruction.program_id_index as usize >= self.message().account_keys.len() {
Expand All @@ -407,7 +407,11 @@ impl Transaction {
.map(|instruction| instruction.data.as_ref())
.collect();
let data = &instruction.data;
let e = verify_eth_addresses(data, &instruction_datas);
let e = verify_eth_addresses(
data,
&instruction_datas,
libsecp256k1_0_5_upgrade_enabled,
);
e.map_err(|_| TransactionError::InvalidAccountIndex)?;
}
}
Expand Down

0 comments on commit abe5a0a

Please sign in to comment.