Fix for modexp overflow in debug mode (#578)

* fix modexp overflow panic in debug mode

* Added one more unit test for modexp

* Remove redundant bytes from modexp unit test

Co-authored-by: POA <33550681+poa@users.noreply.github.com>
This commit is contained in:
Rim Rakhimov 2021-11-30 10:33:40 +03:00 committed by GitHub
parent 3b19a79c37
commit 405738c791
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -203,11 +203,11 @@ impl ModexpPricer {
let (base_len, exp_len) = (base_len_u256.low_u64(), exp_len_u256.low_u64()); let (base_len, exp_len) = (base_len_u256.low_u64(), exp_len_u256.low_u64());
// read fist 32-byte word of the exponent. // read fist 32-byte word of the exponent.
let exp_low = if base_len + 96 >= input.len() as u64 { let exp_low = if base_len.wrapping_add(96) >= input.len() as u64 {
U256::zero() U256::zero()
} else { } else {
buf.iter_mut().for_each(|b| *b = 0); buf.iter_mut().for_each(|b| *b = 0);
let mut reader = input[(96 + base_len as usize)..].chain(io::repeat(0)); let mut reader = input[(base_len as usize).wrapping_add(96)..].chain(io::repeat(0));
let len = min(exp_len, 32) as usize; let len = min(exp_len, 32) as usize;
reader reader
.read_exact(&mut buf[(32 - len)..]) .read_exact(&mut buf[(32 - len)..])
@ -1728,6 +1728,33 @@ mod tests {
native: EthereumBuiltin::from_str("modexp").unwrap(), native: EthereumBuiltin::from_str("modexp").unwrap(),
}; };
// test for potential base len overflow
{
let input = hex!(
"
00000000000000000000000000000000ffffffffffffffffffffffffffffffff
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000001
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
03
ff"
);
let expected_cost = U256::max_value();
assert_eq!(f.cost(&input[..], 0), expected_cost);
}
// another test for potential base len overflow
{
let input = hex!(
"
00000000000000000000000000000000ffffffffffffffffffffffffffffffff
0000000000000000000000000000000000000000000000000000000000000020
0000000000000000000000000000000000000000000000000000000000000020"
);
let expected_cost = U256::max_value();
assert_eq!(f.cost(&input[..], 0), expected_cost);
}
// test for potential gas cost multiplication overflow // test for potential gas cost multiplication overflow
{ {
let input = hex!("0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000003b27bafd00000000000000000000000000000000000000000000000000000000503c8ac3"); let input = hex!("0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000003b27bafd00000000000000000000000000000000000000000000000000000000503c8ac3");
@ -1840,6 +1867,38 @@ mod tests {
} }
} }
#[test]
fn modexp2565() {
let pricer = Modexp2565Pricer {};
// test for potential base len overflow
{
let input = hex!(
"
00000000000000000000000000000000ffffffffffffffffffffffffffffffff
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000001
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
03
ff"
);
let expected_cost = U256::max_value();
assert_eq!(pricer.cost(&input[..]), expected_cost);
}
// another test for potential base len overflow
{
let input = hex!(
"
00000000000000000000000000000000ffffffffffffffffffffffffffffffff
0000000000000000000000000000000000000000000000000000000000000020
0000000000000000000000000000000000000000000000000000000000000020"
);
let expected_cost = U256::max_value();
assert_eq!(pricer.cost(&input[..]), expected_cost);
}
}
#[test] #[test]
fn bn128_add() { fn bn128_add() {
let f = Builtin { let f = Builtin {