Skip to content

cabi hardening: host-side int range asserts; MemInst grow-safety note; transcoder defensive guards #96

Description

@lann

Severity: low — posture/defense-in-depth; no guest-observable deviation.

  1. Out-of-range host integers wrap silently on store (cabi/memory.ts:127-141
    storeInt; mirrored in bulk_lists.ts:164-179) where the reference
    raises a host-precondition error (definitions.py:1568-1569
    int.to_bytes OverflowError). A buggy embedder value corrupts data
    instead of failing loudly (e.g. {x: 300} into record{x: u8} stores
    44). Add assert_ range checks on the scalar path; measure before
    adding to the bulk path (bulk_lists.ts:8-11 documents wrap as
    intended — if kept, align the docs instead).

  2. MemInst (cabi/memory.ts:20-33) caches buffer views forever — stale
    after memory.grow; production is safe only because the executor
    substitutes LiveMemory (exec/boundary.ts:97-160). Add a doc comment:
    must not be used with growable memory.

  3. Transcoders omit wasmtime's runtime defensive checks:
    utf8-to-compact-utf16 (intrinsics/transcode.ts:398-414) has no
    dst-capacity guard corresponding to libcalls.rs:308-312's zip, and no
    op asserts src/dst non-overlap (libcalls.rs:166-177). Unreachable under
    FACT's guarantees, but if the invariant ever broke the port corrupts
    guest memory or throws RangeError where wasmtime truncates/panics. Add
    cheap guards that fail as Traps.

Found in the 2026-08-10 adversarial conformance review (runtime + translator vs component-model @ 73b7ad5 definitions.py; wasmtime-environ 47.0.3 treated as trusted).

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