Skip to content

#326 Finding A: path-F gate misses absolute addresses used as values (no-reloc, no direct load/store) #339

Description

@avrabe

Follow-up from the Mythos discover pass on the #326 reloc-consumer (PR pending).

The gap

The path-F hard-error gate (module_has_direct_memory_access in merger.rs) rejects a no-reloc, non-zero-base module only when it performs a direct load/store. It does NOT catch a module that references an absolute address purely as a valuei32.const <abs>; call $import (a canonical-ABI &BUF handed to an imported memcpy/fd_write) or i32.const <abs>; return. With no reloc metadata, the legacy path emits the const verbatim (un-rebased), so such a module hands an un-rebased pointer to the host / another component → silent cross-component corruption. This is exactly datapoint A's pattern (a buffer pointer passed to an import).

Why the naive fix is wrong (empirically confirmed)

Broadening the gate to reject any i32.const/i64.const regresses the legitimate bulk-only case: test_address_rebasing_end_to_end uses i32.const values that are safely consumed by rebased bulk-memory ops (memory.copy/fill/init, dynamically rebased by append_rebased_address). The naive broadening rejected it (test FAILED). So a bare const is indistinguishable from an integer, and bulk-op-consumed consts are safe — a sound fix needs data-flow analysis to tell an escaping address-const from a rebased-bulk-consumed or plain-integer const.

Scope / severity

  • Medium. Silent memory corruption, but only on the no-reloc path (already the unsupported path — meld hard-errors the load/store subset and the error advises --emit-relocs).
  • Does NOT affect the supported path: --emit-relocs inputs (e.g. gale's) carry reloc metadata, so their address consts are correctly rebased via reloc.CODE.
  • The residual gap is documented in module_has_direct_memory_access's doc comment (KNOWN LIMITATION).

Proposed fix

Data-flow-aware gate: reject a no-reloc non-zero-base module iff it has an i32.const/i64.const that reaches a call/call_indirect/return/store WITHOUT being consumed by a dynamically-rebased bulk-memory op. (Or: require reloc metadata for ANY no-reloc non-zero-base module with a non-trivial code section, accepting the loss of the bulk-only-without-relocs convenience — a scope decision.)

Refs #326, ADR-6 (path-F), SR-48.

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