Skip to content

Malformed module panics the decoder on 32-bit targets: unbounded vector length reaches Layout::array(..).unwrap() #158

Description

@kadircanyildirm-crypto

A 15-byte malformed module panics the decoder on 32-bit targets. Verified on a clean checkout of main @ 096c71cfa.

Reader::read_vec_in (src/reader.rs:459) passes a module-supplied vector length straight to the allocator:

let len = self.read_u32()?;
let mut out = Vec::new_in(alloc, len)?;

Vec::new_in (src/util/vec.rs:137) then unwraps the layout:

unsafe { alloc.alloc(Layout::array::<T>(capacity as usize).unwrap())? }

On 32-bit isize::MAX is 2147483647, so a declared length of 0xFFFFFFFF overflows the layout for any element type and the unwrap panics. It runs before alloc.alloc, so a size-limited allocator does not protect against it.

The stack-based sibling already guards this: read_vec_stack (src/reader.rs:436-438) checks len and returns ValidationError::VecTooLong, which already exists and is already wired through the C API and the spec-test harness. Only the heap path skips it. read_vec feeds the type, import, function and global sections, code locals, FuncType signatures and export names, and is reachable from spacewasm_load_module.

Reproduce

The 32-bit regression suite is green first — 13 passed; 0 failed. Append to tests/regression/decode-errors.wast, a type section of size 5 declaring 0xFFFFFFFF entries:

(assert_invalid
  (module binary "\00asm\01\00\00\00\01\05\ff\ff\ff\ff\0f")
  "length out of bounds")
$ cargo test -p spacewasm --target i686-unknown-linux-gnu --test regression_integration decode_errors
test decode_errors ... FAILED
thread 'decode_errors' panicked at src/util/vec.rs:137:72:
called `Result::unwrap()` on an `Err` value: LayoutError

The same case passes on x86-64, where the layout is valid and the module is rejected with Eof — so it doubles as a regression test. Looks like an instance of #39.

#156 fixed this same unwrap shape in src/util/rc.rs but not in vec.rs; where the bound belongs is your call. Happy to send the test as a PR.


Disclosure per AI_POLICY.md. Tool: Claude Code. Assistance: bug diagnosis and reporting plus the .wast case; no AI-generated change to src/ is proposed. Every line reference and result comes from a clean checkout of 096c71cfa that I built and ran myself.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions