Skip to content

wasmparser: Relocation range end can wrap on 32-bit targets#2497

Merged
dicej merged 2 commits intobytecodealliance:mainfrom
dip-proto:relocation-range-end-can-wrap-on-32-bit-targets
Apr 17, 2026
Merged

wasmparser: Relocation range end can wrap on 32-bit targets#2497
dicej merged 2 commits intobytecodealliance:mainfrom
dip-proto:relocation-range-end-can-wrap-on-32-bit-targets

Conversation

@jedisct1
Copy link
Copy Markdown
Contributor

RelocationEntry::relocation_range() derived a Range 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

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
@jedisct1 jedisct1 requested a review from a team as a code owner April 17, 2026 11:17
@jedisct1 jedisct1 requested review from dicej and removed request for a team April 17, 2026 11:17
Copy link
Copy Markdown
Collaborator

@dicej dicej left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@dicej dicej added this pull request to the merge queue Apr 17, 2026
Merged via the queue into bytecodealliance:main with commit d99e559 Apr 17, 2026
37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants