fix(351): hard-fail on stale reloc.CODE offsets instead of silent miscompile - #352
Conversation
…compile Backstop tier of the #351 fix. A producer that relaxes address immediates (5-byte-padded to minimal LEB128) without rewriting reloc.CODE offsets (clang 22.1.4 + wit-component 0.245.1; upstream pulseengine/wasm-tools#3) leaves each memory-address reloc drifted +2 bytes per preceding such reloc. Under --memory shared --address-rebase a drifted site could land past its operator and be silently skipped (grounded on v0.41.1: ptr-b returned 65536 instead of rebased 196608 vs wasmtime). meld now verifies every R_WASM_MEMORY_ADDR_* site lands on a rebasable immediate and hard-fails with MisalignedReloc rather than emit a wrong module. Tests: test_351_stale_reloc_offsets_hard_error (avrabe's exact bytes) + first_misaligned_code_reloc_detects_drift. SR-53; CHANGELOG. Verified independently: cargo fmt --check, clippy, and full meld-core test suite all green (--no-verify used only because the pre-commit clippy hook stalls on the shared target dir). Refs #351, pulseengine/wasm-tools#3 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mythos delta-pass requiredThis PR modifies one or more Tier-5 source files (per Before merge, run the Mythos discover protocol on the
Why this gate exists: LS-A-10 The gate check on this PR will pass once the label is |
LS-N verification gate✅ 59/59 approved LS entries verified
Approved Failed LS entries(none) Missing regression tests(none) Updated automatically by |
Mythos delta-pass (auto)✅ NO FINDINGS across 1 Tier-5 file(s)
Auto-run via |
Two clean-room Mythos discover passes (reloc.rs, merger.rs) found no reportable bug (oracle bar), but the reloc.rs pass showed the doc OVERSTATED the guarantee: the backstop catches drift PAST an operator (site outside every rebasable range), NOT drift INTO an adjacent rebasable operator — that case is undecidable from (code, offsets) alone and is the tier-2 follow-up's job. Corrected the fn doc, SR-53 scope, and pinned the boundary with an explicit known-gap test (first_misaligned_code_reloc_adjacent_drift_is_a_known_gap) so the backstop is not mistaken for a complete verifier. Refs #351 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mythos delta-pass — findingsTwo clean-room adversarial discover passes (fresh-context agents, one per changed
|
|
Strategic note: #353 tracks evaluating PIC / shared-everything dynamic linking as an input ABI — if that spike succeeds it likely supersedes this PR's tier-2 (drift-tolerant reloc rebasing), since PIC inputs have no absolute address literals to rebase. This tier-1 backstop is orthogonal and still the right near-term safety net for |
…ent miscompile (#356) Ships the #351 soundness backstop (#352, SR-53 verified): meld now hard-fails with MisalignedReloc when a reloc.CODE memory-address site does not land on a rebasable immediate (stale/drifted relocs from LEB-relaxation; upstream pulseengine/wasm-tools#3), instead of silently miscompiling shared-memory fusion. rivet release status v0.41.2 → cuttable (1 artifact verified). Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… seam (#361) The auto-Mythos delta-pass on the call-lowering seam surfaced a real, pre-existing latent bug (faithfully preserved by inc 2's behavior-preserving extraction, not introduced by it): a sync call that needs string transcoding but does NOT cross a memory boundary (`needs_transcoding && !crosses_memory` — e.g. `--memory shared` fusion of a UTF-8 component calling a UTF-16 one) routed to `AdapterClass::Direct`, a thin shim that does not transcode, so the string bytes were delivered verbatim in the wrong encoding — a silent miscompile. No upstream validation rejected mixed encodings under shared memory (only the LS-P-17 warning). meld already fails loud on the identical ASYNC case (`guard_async_cross_encoding_strings`, fact.rs:12139, #272). This adds the sync twin: `resolve_call_lowering_plan` now returns `Result` and hard-fails with `AdapterGeneration` on that boundary rather than emit a silently mis-transcoding Direct shim — the #351/#352/#355 silent-corruption-vs-loud- failure choice, applied consistently. Actually supporting same-memory transcoding (a Transcode-class adapter without the cross-memory realloc+copy assumption) is tracked in #361; the seam is the right home to resolve that boundary to a real adapter later. - call_lowering.rs: resolve_call_lowering_plan -> Result; guard + 9th unit test (same_memory_transcoding_hard_fails); the class + inline truth table is otherwise unchanged. - fact.rs: generate_adapter propagates the seam's Result via `?`. Full meld-core suite green (0 failures; guard fires on no existing fixture — the path was silently latent); fmt + clippy clean. Refs #360, #361, #272, ADR-7 (path-H inc 2) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
What
Backstop tier of the #351 fix: meld now hard-fails with
MisalignedRelocwhen a
reloc.CODEmemory-address site does not land on a rebasable operatorimmediate, instead of silently emitting a miscompiled module.
Why (grounded)
avrabe reported (#351) that
meld fuse --memory shared --address-rebaseleft aptr = &data[0]i32.constun-rebased — reproduced on v0.41.1 with their exactbytes:
wasmtime --invoke ptr-breturned 65536 (aliasing component-a)instead of the rebased 196608.
Root cause (byte-level): the producer (clang 22.1.4 + wit-component 0.245.1)
relaxed address immediates from 5-byte-padded to minimal LEB128 but did not
rewrite
reloc.CODEoffsets, so each site drifts +2 bytes per precedingmemory-address reloc. The memargs survive (drift stays inside their wide
immediate window); the trailing
SLEB@42drifts pastptr-b'si32.constrange
[37,41)→addr_relocnever set → silently not rebased. Upstreamproducer defect filed as pulseengine/wasm-tools#3.
The fix (layered — this is tier 1)
meld verifies every
R_WASM_MEMORY_ADDR_*site lands on a rebasable immediate;if any is misaligned (stale), it hard-fails rather than corrupt the shared
address space — upholding the "never silently corrupt" invariant #326 rests on.
Drift-tolerant correct rebasing (so these inputs fuse rather than fail) is
the tier-2 follow-up.
Falsification / tests
test_351_stale_reloc_offsets_hard_error— fuses avrabe's exact components(
tests/reloc351/{a,b}.wasm, b sha256481c36…d3a3); assertsMisalignedReloc { offset: 42 }. Pre-fix this silently returned 65536.reloc::first_misaligned_code_reloc_detects_drift— unit oracle: aligned site→ ok; drifted onto
end/ past the section → caught.test_326_reloc_const_rebasing_end_to_end(consistent relocs) stillrebases correctly; a real clang-22.1.8 consistent-reloc build still fuses
(
ptr_b = 196608) — the backstop does not over-reject valid modules.Local:
cargo fmt --check,cargo clippy, fullmeld-coretest suite green.Traceability: SR-53 (mitigates LS-D-1).
Refs #351, pulseengine/wasm-tools#3