From cca72aba47a675380a3c87199c7ed0406e3281c2 Mon Sep 17 00:00:00 2001 From: publicqi <56060664+publicqi@users.noreply.github.com> Date: Mon, 25 Nov 2024 03:07:34 -0800 Subject: [PATCH] fix: bail incomplete bytecode sequence disassemble (#9390) --- crates/cast/src/lib.rs | 21 ++++++++++++++++++++- crates/evm/core/src/ic.rs | 9 +++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/crates/cast/src/lib.rs b/crates/cast/src/lib.rs index 39e821dc91f1..b5b719e39ae8 100644 --- a/crates/cast/src/lib.rs +++ b/crates/cast/src/lib.rs @@ -2017,7 +2017,7 @@ impl SimpleCast { pub fn disassemble(code: &[u8]) -> Result { let mut output = String::new(); - for step in decode_instructions(code) { + for step in decode_instructions(code)? { write!(output, "{:08x}: ", step.pc)?; if let Some(op) = step.op { @@ -2290,4 +2290,23 @@ mod tests { r#"["0x2b5df5f0757397573e8ff34a8b987b21680357de1f6c8d10273aa528a851eaca","0x","0x","0x2838ac1d2d2721ba883169179b48480b2ba4f43d70fcf806956746bd9e83f903","0x","0xe46fff283b0ab96a32a7cc375cecc3ed7b6303a43d64e0a12eceb0bc6bd87549","0x","0x1d818c1c414c665a9c9a0e0c0ef1ef87cacb380b8c1f6223cb2a68a4b2d023f5","0x","0x","0x","0x236e8f61ecde6abfebc6c529441f782f62469d8a2cc47b7aace2c136bd3b1ff0","0x","0x","0x","0x","0x"]"# ) } + + #[test] + fn disassemble_incomplete_sequence() { + let incomplete = &hex!("60"); // PUSH1 + let disassembled = Cast::disassemble(incomplete); + assert!(disassembled.is_err()); + + let complete = &hex!("6000"); // PUSH1 0x00 + let disassembled = Cast::disassemble(complete); + assert!(disassembled.is_ok()); + + let incomplete = &hex!("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // PUSH32 with 31 bytes + let disassembled = Cast::disassemble(incomplete); + assert!(disassembled.is_err()); + + let complete = &hex!("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // PUSH32 with 32 bytes + let disassembled = Cast::disassemble(complete); + assert!(disassembled.is_ok()); + } } diff --git a/crates/evm/core/src/ic.rs b/crates/evm/core/src/ic.rs index 2711f8933543..fcabf2a18b41 100644 --- a/crates/evm/core/src/ic.rs +++ b/crates/evm/core/src/ic.rs @@ -1,4 +1,5 @@ use alloy_primitives::map::HashMap; +use eyre::Result; use revm::interpreter::{ opcode::{PUSH0, PUSH1, PUSH32}, OpCode, @@ -100,7 +101,7 @@ pub struct Instruction<'a> { } /// Decodes raw opcode bytes into [`Instruction`]s. -pub fn decode_instructions(code: &[u8]) -> Vec> { +pub fn decode_instructions(code: &[u8]) -> Result>> { let mut pc = 0; let mut steps = Vec::new(); @@ -108,10 +109,14 @@ pub fn decode_instructions(code: &[u8]) -> Vec> { let op = OpCode::new(code[pc]); let immediate_size = op.map(|op| immediate_size(op, &code[pc + 1..])).unwrap_or(0) as usize; + if pc + 1 + immediate_size > code.len() { + eyre::bail!("incomplete sequence of bytecode"); + } + steps.push(Instruction { op, pc, immediate: &code[pc + 1..pc + 1 + immediate_size] }); pc += 1 + immediate_size; } - steps + Ok(steps) }