diff --git a/programs/bpf_loader/src/syscalls.rs b/programs/bpf_loader/src/syscalls.rs index 3af6c2f806..59e12f4597 100644 --- a/programs/bpf_loader/src/syscalls.rs +++ b/programs/bpf_loader/src/syscalls.rs @@ -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, @@ -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()), }), ); @@ -1366,6 +1368,7 @@ pub struct SyscallSecp256k1Recover<'a> { cost: u64, compute_meter: Rc>, loader_id: &'a Pubkey, + libsecp256k1_0_5_upgrade_enabled: bool, } impl<'a> SyscallObject for SyscallSecp256k1Recover<'a> { @@ -1426,7 +1429,13 @@ impl<'a> SyscallObject 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()); diff --git a/sdk/program/src/secp256k1_recover.rs b/sdk/program/src/secp256k1_recover.rs index 4a6433d5da..6325a885bd 100644 --- a/sdk/program/src/secp256k1_recover.rs +++ b/sdk/program/src/secp256k1_recover.rs @@ -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])) diff --git a/sdk/src/secp256k1_instruction.rs b/sdk/src/secp256k1_instruction.rs index 37585eb18b..c6d9bd2b16 100644 --- a/sdk/src/secp256k1_instruction.rs +++ b/sdk/src/secp256k1_instruction.rs @@ -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); @@ -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)?; @@ -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] @@ -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) ); diff --git a/sdk/src/transaction.rs b/sdk/src/transaction.rs index 2c0fc1992e..b895333e8b 100644 --- a/sdk/src/transaction.rs +++ b/sdk/src/transaction.rs @@ -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() { @@ -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)?; } }