From 66963299d1104d1542bd03612e9ef2893feaff00 Mon Sep 17 00:00:00 2001 From: Andronik Ordian Date: Fri, 18 Oct 2019 12:44:11 +0200 Subject: [PATCH 1/2] [ethcore/builtin]: do not panic in blake2pricer on short input --- ethcore/builtin/src/lib.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/ethcore/builtin/src/lib.rs b/ethcore/builtin/src/lib.rs index 795bf6f4796..a24c1f36a93 100644 --- a/ethcore/builtin/src/lib.rs +++ b/ethcore/builtin/src/lib.rs @@ -18,7 +18,7 @@ use std::{ cmp::{max, min}, - convert::TryFrom, + convert::{TryFrom, TryInto}, io::{self, Read, Cursor}, mem::size_of, }; @@ -56,11 +56,14 @@ pub type Blake2FPricer = u64; impl Pricer for Blake2FPricer { fn cost(&self, input: &[u8], _at: u64) -> U256 { - use std::convert::TryInto; - let (rounds_bytes, _) = input.split_at(std::mem::size_of::()); + const FOUR: usize = std::mem::size_of::(); // Returning zero if the conversion fails is fine because `execute()` will check the length // and bail with the appropriate error. - let rounds = u32::from_be_bytes(rounds_bytes.try_into().unwrap_or([0u8; 4])); + if input.len() < FOUR { + return U256::zero(); + } + let (rounds_bytes, _) = input.split_at(FOUR); + let rounds = u32::from_be_bytes(rounds_bytes.try_into().unwrap_or([0u8; FOUR])); U256::from(*self as u128 * rounds as u128) } } From f934934b13363d8f3dc465d52ca1c47402b98fe9 Mon Sep 17 00:00:00 2001 From: Andronik Ordian Date: Fri, 18 Oct 2019 12:58:18 +0200 Subject: [PATCH 2/2] [ethcore/builtin]: add a test for blake2pricer --- ethcore/builtin/src/lib.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/ethcore/builtin/src/lib.rs b/ethcore/builtin/src/lib.rs index a24c1f36a93..78633a12ef7 100644 --- a/ethcore/builtin/src/lib.rs +++ b/ethcore/builtin/src/lib.rs @@ -711,6 +711,19 @@ mod tests { assert_eq!(f.cost(&input[..], 0), U256::from(123*5)); } + #[test] + fn blake2f_cost_on_invalid_length() { + let f = Builtin { + pricer: Box::new(123), + native: ethereum_builtin("blake2_f").expect("known builtin"), + activate_at: 0, + }; + // invalid input (too short) + let input = hex!("00"); + + assert_eq!(f.cost(&input[..], 0), U256::from(0)); + } + #[test] fn blake2_f_is_err_on_invalid_length() { let blake2 = ethereum_builtin("blake2_f").expect("known builtin");