Repository navigation
Description
Problem
pkgs/mcpx/internal/wasmtools (the #1970 WASM tool-source spike, merged today in #2002) documents a guest ABI whose first required export is memory (package doc, wasmtools.go:19-27), but Load validates only the four ABI functions:
for _, fn := range []string{inputPtrFn, outputPtrFn, listFn, callFn} {
if mod.ExportedFunction(fn) == nil {
rt.Close(ctx)
return nil, fmt.Errorf("wasmtools: guest does not export %s", fn)
}
}(wasmtools.go:116-122 — no mod.Memory() check.)
A guest that exports the four functions but no memory is therefore accepted, and the first use crashes the host with a nil-pointer panic instead of returning an error:
readOutput:s.mod.Memory().Read(...)(wasmtools.go:133-136) —Memory()is nil for such a guest.CallTool:s.mod.Memory()thenmem.Write(...)(wasmtools.go:163-166) — same nil dereference.- The granted
loghandler also dereferences the caller's memory (wasmtools.go:107-110).
For a package whose whole purpose is hosting untrusted guests behind a capability boundary, a malformed guest must be a clean Load (or call) error, never a host panic.
Evidence (verified this run, main 26221fcc)
Probe on the laptop (~/git/fleet/probe-2026-10-28-laneB-wasmlogs/, verbatim copy of the package from main 26221fcc). The probe guest is a 124-byte hand-assembled module exporting exactly mcpx_input_ptr, mcpx_output_ptr, mcpx_list_tools, mcpx_call_tool (correct signatures, each returning 0) and no memory export and no imports (testdata/nomem.wasm in the probe dir):
=== RUN TestProbeNoMemoryGuest
probe_nomem_test.go:26: Load ACCEPTED no-memory guest; calling ListTools (panic expected)
probe_nomem_test.go:29: PANIC from ListTools on no-memory guest: runtime error: invalid memory address or nil pointer dereference
--- PASS: TestProbeNoMemoryGuest (0.00s)
The panic was caught by the probe's recover(); in production it propagates out of ListTools/CallTool into the caller. Contrast with the existing grant-denial tests: ungranted imports already fail cleanly at Load — the missing-memory case is the gap in the same validation step.
Why it matters
Deny-by-default instantiation is the spike's headline property (three tests prove import denial). An ABI-validation hole that turns a malformed guest into a host crash undermines that property and, like the unbounded-log issue (#2073, different bug: retention in the log handler), will be inherited by the production registration path (#1885) if not fixed while the package is young.
Acceptance criteria
-
Loadrejects a guest with no exportedmemory, with a descriptive error naming the missing export (mirroring the existingguest does not export %serrors), and closes the runtime on that path as the function-check path does. - No code path in the package can nil-dereference a missing memory: either the
Loadguarantee is total, orreadOutput/CallTool/theloghandler return errors instead of panicking. - A regression test loads a guest with the four functions but no memory export (a small hand-assembled module or equivalent fixture is fine) and asserts a clean error, not a panic.
- Existing tests (
TestListAndCallWithGrantedLog, both grant-denial tests) still pass.
Found by new-issue-creator-code-b (Lane B) this run; not self-solved — whether to also harden the call sites vs. relying on the Load guarantee is triage's pin.
Activity
developing-today commentedon Oct 29, 2026
CODE-992
dezren39 commentedon Oct 29, 2026
🤖 Agent note · filed
6 remaining items
dezren39 commentedon Nov 1, 2026
🤖 Agent note · handed off
dezren39 commentedon Nov 1, 2026
🤖 Agent note · done
dezren39 commentedon Nov 1, 2026
🤖 Agent note · picked up
dezren39 commentedon Nov 1, 2026
🤖 Agent note · picked up
queue/5076-2076-reject-wasmtools-guests-without-exported-memoryalready pushed (commit 7f665a4); opening the PR and completing the task.queue/5076-2076-reject-wasmtools-guests-without-exported-memorydezren39 commentedon Nov 1, 2026
🤖 Agent note · done
pr_openedqueue/5076-2076-reject-wasmtools-guests-without-exported-memory(commit 7f665a4).Merge pull request #4077 from developing-today/queue/5076-2076-reject…