Skip to content
This repository was archived by the owner on Nov 6, 2020. It is now read-only.

Commit 7029dda

Browse files
arkpargavofyork
authored andcommitted
Fixed potential exp len overflow (#6686)
1 parent 0bb845a commit 7029dda

File tree

1 file changed

+25
-9
lines changed

1 file changed

+25
-9
lines changed

ethcore/src/builtin.rs

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -101,18 +101,17 @@ impl Pricer for ModexpPricer {
101101
let exp_len = read_len();
102102
let mod_len = read_len();
103103

104+
if mod_len.is_zero() && base_len.is_zero() {
105+
return U256::zero()
106+
}
107+
104108
let max_len = U256::from(u32::max_value() / 2);
105-
if base_len > max_len || mod_len > max_len {
109+
if base_len > max_len || mod_len > max_len || exp_len > max_len {
106110
return U256::max_value();
107111
}
112+
let (base_len, exp_len, mod_len) = (base_len.low_u64(), exp_len.low_u64(), mod_len.low_u64());
108113

109-
let base_len = base_len.low_u64();
110-
let exp_len = exp_len.low_u64();
111-
let mod_len = mod_len.low_u64();
112114
let m = max(mod_len, base_len);
113-
if m == 0 {
114-
return U256::zero();
115-
}
116115
// read fist 32-byte word of the exponent.
117116
let exp_low = if base_len + 96 >= input.len() as u64 { U256::zero() } else {
118117
let mut buf = [0; 32];
@@ -133,8 +132,7 @@ impl ModexpPricer {
133132
let bit_index = if exp_low.is_zero() { 0 } else { (255 - exp_low.leading_zeros()) as u64 };
134133
if len <= 32 {
135134
bit_index
136-
}
137-
else {
135+
} else {
138136
8 * (len - 32) + bit_index
139137
}
140138
}
@@ -707,6 +705,24 @@ mod tests {
707705
native: ethereum_builtin("modexp"),
708706
activate_at: 0,
709707
};
708+
709+
// test for potential exp len overflow
710+
{
711+
let input = FromHex::from_hex("\
712+
00000000000000000000000000000000000000000000000000000000000000ff\
713+
2a1e530000000000000000000000000000000000000000000000000000000000\
714+
0000000000000000000000000000000000000000000000000000000000000000"
715+
).unwrap();
716+
717+
let mut output = vec![0u8; 32];
718+
let expected = FromHex::from_hex("0000000000000000000000000000000000000000000000000000000000000000").unwrap();
719+
let expected_cost = U256::max_value();
720+
721+
f.execute(&input[..], &mut BytesRef::Fixed(&mut output[..])).expect("Builtin should fail");
722+
assert_eq!(output, expected);
723+
assert_eq!(f.cost(&input[..]), expected_cost.into());
724+
}
725+
710726
// fermat's little theorem example.
711727
{
712728
let input = FromHex::from_hex("\

0 commit comments

Comments
 (0)