Skip to content

Commit d99e559

Browse files
authored
wasmparser: Relocation range end can wrap on 32-bit targets (#2497)
* wasmparser: Relocation range end can wrap on 32-bit targets RelocationEntry::relocation_range() derived a Range<usize> from untrusted relocation offsets using `self.offset as usize` and start + self.ty.extent(). On 32-bit targets, large parsed offsets can overflow the end computation, causing a debug-build panic or release-build wraparound instead of rejection. That can be reproduced with a 30-byte wasm module consisting of a header and a single `reloc.CODE` custom section with one entry: | Field | Value | Encoding | |--------|---------------------------|--------------------------------| | type | `FunctionIndexLeb` (0x00) | extent = 5, no addend | | offset | `0xFFFF_FFFC` | LEB128: `FC FF FF FF 0F` | | index | 0 | LEB128: `00` | $ cargo build -p wasmparser --example reloc_overflow --target wasm32-wasip1 $ wasmtime target/wasm32-wasip1/debug/examples/reloc_overflow.wasm parsed: type=FunctionIndexLeb, offset=0xFFFFFFFC, extent=5 thread 'main' panicked at crates/wasmparser/src/readers/core/reloc.rs:246:33: attempt to add with overflow In release mode the panic becomes a silent wraparound: $ cargo build --release -p wasmparser --example reloc_overflow --target wasm32-wasip1 $ wasmtime target/wasm32-wasip1/release/examples/reloc_overflow.wasm parsed: type=FunctionIndexLeb, offset=0xFFFFFFFC, extent=5 relocation_range() = 0xFFFFFFFC..0x1 BUG: range end < start due to overflow Autonomously found by https://swival.dev /scan * FOrmat
1 parent 0285a46 commit d99e559

1 file changed

Lines changed: 6 additions & 2 deletions

File tree

  • crates/wasmparser/src/readers/core

crates/wasmparser/src/readers/core/reloc.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,12 @@ pub struct RelocationEntry {
242242
impl RelocationEntry {
243243
/// Byte range relative to the start of the section indicated by
244244
/// `RelocSectionReader::section` targeted by this relocation.
245-
pub fn relocation_range(&self) -> Range<usize> {
246-
(self.offset as usize)..(self.offset as usize + self.ty.extent())
245+
pub fn relocation_range(&self) -> Result<Range<usize>> {
246+
let start = self.offset as usize;
247+
let end = start
248+
.checked_add(self.ty.extent())
249+
.ok_or_else(|| crate::BinaryReaderError::new("relocation range end overflow", start))?;
250+
Ok(start..end)
247251
}
248252
}
249253

0 commit comments

Comments
 (0)