Skip to content

Commit 2af87aa

Browse files
committed
fix(EVM-1173): keep ABI mutator values in valid ranges
1 parent bd78144 commit 2af87aa

File tree

1 file changed

+28
-8
lines changed
  • tests/fuzzer/fuzz/fuzz_targets/bootloader/common

1 file changed

+28
-8
lines changed

tests/fuzzer/fuzz/fuzz_targets/bootloader/common/mod.rs

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,8 @@ fn mutate_zksync_transaction(tx: &mut TransactionData, rng: &mut StdRng) {
284284
}
285285
1 => mutate_address_inplace(&mut tx.from, rng),
286286
2 => mutate_address_inplace(&mut tx.to, rng),
287-
3 => tx.gas_limit = mutate_u256_vec(tx.gas_limit, rng),
288-
4 => tx.gas_per_pubdata_limit = mutate_u256_vec(tx.gas_per_pubdata_limit, rng),
287+
3 => tx.gas_limit = mutate_u64_field(tx.gas_limit, rng),
288+
4 => tx.gas_per_pubdata_limit = mutate_u32_field(tx.gas_per_pubdata_limit, rng),
289289
5 => tx.max_fee_per_gas = mutate_u256_vec(tx.max_fee_per_gas, rng),
290290
6 => tx.max_priority_fee_per_gas = mutate_u256_vec(tx.max_priority_fee_per_gas, rng),
291291
7 => tx.nonce = mutate_u256_vec(tx.nonce, rng),
@@ -342,6 +342,22 @@ fn mutate_u256_vec(num: U256, rng: &mut StdRng) -> U256 {
342342
U256::from_be_bytes(mutated_bytes)
343343
}
344344

345+
fn mutate_u64_field(num: U256, rng: &mut StdRng) -> U256 {
346+
mutate_low_bytes(num, 8, rng)
347+
}
348+
349+
fn mutate_u32_field(num: U256, rng: &mut StdRng) -> U256 {
350+
mutate_low_bytes(num, 4, rng)
351+
}
352+
353+
fn mutate_low_bytes(num: U256, bytes_to_mutate: usize, rng: &mut StdRng) -> U256 {
354+
let mut mutated_bytes = num.to_be_bytes();
355+
let start = 32usize.saturating_sub(bytes_to_mutate);
356+
let idx = rng.gen_range(start..mutated_bytes.len());
357+
mutated_bytes[idx] ^= rng.gen::<u8>();
358+
U256::from_be_bytes(mutated_bytes)
359+
}
360+
345361
#[allow(dead_code)]
346362
fn mutate_u8(num: u8, rng: &mut StdRng) -> u8 {
347363
num ^ rng.gen::<u8>()
@@ -384,16 +400,20 @@ fn pad32(v: &mut Vec<u8>) {
384400
}
385401
}
386402

403+
fn clamp_to_u32(value: usize) -> u32 {
404+
u32::try_from(value).unwrap_or(u32::MAX)
405+
}
406+
387407
// Push a dynamic `bytes` arg: put its offset in head, then tail = len + data + pad
388408
pub(crate) fn abi_push_bytes(
389409
head: &mut Vec<[u8; 32]>,
390410
tail: &mut Vec<u8>,
391411
data: &[u8],
392412
head_size_bytes: usize,
393413
) {
394-
let offset = U256::from(head_size_bytes + tail.len());
395-
head.push(enc_u256(offset));
396-
tail.extend_from_slice(&enc_u256(U256::from(data.len() as u64)));
414+
let offset = clamp_to_u32(head_size_bytes + tail.len());
415+
head.push(enc_u32(offset));
416+
tail.extend_from_slice(&enc_u32(clamp_to_u32(data.len())));
397417
tail.extend_from_slice(data);
398418
pad32(tail);
399419
}
@@ -405,9 +425,9 @@ pub(crate) fn abi_push_bytes32_array(
405425
items: &[[u8; 32]],
406426
head_size_bytes: usize,
407427
) {
408-
let offset = U256::from(head_size_bytes + tail.len());
409-
head.push(enc_u256(offset));
410-
tail.extend_from_slice(&enc_u256(U256::from(items.len() as u64)));
428+
let offset = clamp_to_u32(head_size_bytes + tail.len());
429+
head.push(enc_u32(offset));
430+
tail.extend_from_slice(&enc_u32(clamp_to_u32(items.len())));
411431
for it in items {
412432
tail.extend_from_slice(it);
413433
}

0 commit comments

Comments
 (0)