Hello, and thank you for maintaining this crate.
I found a sanitizer/Miri failure reachable through public crate APIs using safe Rust code. I may be missing crate-specific preconditions, but the behavior looks worth checking because safe callers should not be able to trigger undefined behavior.
Summary
- Crate:
revm-interpreter
- Version tested:
35.0.1
- API paths with similar failures observed:
ExtBytecode::read_u8/read_u16/read_slice
ExtBytecode::read_offset_u16
ExtBytecode::opcode/pc
ExtBytecode::relative_jump/absolute_jump
SharedMemory::set
SharedMemory::set_data
SharedMemory::resize
Observed diagnostics
Miri undefined behavior: error: Undefined Behavior: memory access failed: attempting to access 2 bytes, but got alloc88868 which is only 1 byte from the end of the allocation
Unsafe precondition violation: unsafe precondition(s) violated: slice::get_unchecked_mut requires that the range is within the slice
Reproduction
The snippets below are minimal readable reproducers. Each PoC also includes the source location most relevant to the reported failure.
PoC 1: test_revm_interpreter10::generated_test_10
Relevant source location:
src/interpreter/ext_bytecode.rs:167-168: read_u16 performs an unchecked pointer read at the current instruction pointer.
src/interpreter/ext_bytecode.rs:182-188: read_offset_u16 applies an unchecked offset before reading two bytes.
Readable equivalent PoC:
use revm_interpreter::interpreter::ExtBytecode;
use revm_interpreter::interpreter_types::{Immediates, Jumps};
#[test]
fn poc() {
let mut bytecode = ExtBytecode::default();
bytecode.relative_jump(isize::MAX);
let _ = bytecode.read_offset_u16(isize::MAX);
}
Observed diagnostic:
error: Undefined Behavior: memory access failed: attempting to access 2 bytes, but got alloc88868 which is only 1 byte from the end of the allocation
PoC 2: test_revm_interpreter202::generated_test_202
Relevant source location:
src/interpreter/shared_memory.rs:531: internal set_data receives unchecked offsets and length.
src/interpreter/shared_memory.rs:543-545: it uses unchecked slice ranges derived from those values.
Readable equivalent PoC:
use revm_interpreter::interpreter_types::MemoryTr;
#[test]
fn poc() {
let mut memory = revm_interpreter::SharedMemory::new();
memory.set(usize::MAX, &[0xff; 8]);
let _ = memory.resize(0);
memory.set_data(usize::MAX, 0, usize::MAX, &[0xff; 8]);
}
Observed diagnostic:
unsafe precondition(s) violated: slice::get_unchecked_mut requires that the range is within the slice
Source review and suggested fix
Brief reasoning:
- Several public trait methods perform unchecked reads from the instruction pointer.
- If those methods are safe to call from outside the crate, callers can trigger out-of-bounds or misaligned access through ordinary safe code.
Suggested fix:
- Make the unchecked readers internal or
unsafe, and add bounds checks or fallible accessors for the public API.
Thanks again for taking a look.
Hello, and thank you for maintaining this crate.
I found a sanitizer/Miri failure reachable through public crate APIs using safe Rust code. I may be missing crate-specific preconditions, but the behavior looks worth checking because safe callers should not be able to trigger undefined behavior.
Summary
revm-interpreter35.0.1ExtBytecode::read_u8/read_u16/read_sliceExtBytecode::read_offset_u16ExtBytecode::opcode/pcExtBytecode::relative_jump/absolute_jumpSharedMemory::setSharedMemory::set_dataSharedMemory::resizeObserved diagnostics
Reproduction
The snippets below are minimal readable reproducers. Each PoC also includes the source location most relevant to the reported failure.
PoC 1:
test_revm_interpreter10::generated_test_10Relevant source location:
src/interpreter/ext_bytecode.rs:167-168:read_u16performs an unchecked pointer read at the current instruction pointer.src/interpreter/ext_bytecode.rs:182-188:read_offset_u16applies an unchecked offset before reading two bytes.Readable equivalent PoC:
Observed diagnostic:
PoC 2:
test_revm_interpreter202::generated_test_202Relevant source location:
src/interpreter/shared_memory.rs:531: internalset_datareceives unchecked offsets and length.src/interpreter/shared_memory.rs:543-545: it uses unchecked slice ranges derived from those values.Readable equivalent PoC:
Observed diagnostic:
Source review and suggested fix
Brief reasoning:
Suggested fix:
unsafe, and add bounds checks or fallible accessors for the public API.Thanks again for taking a look.