ReviewOS

zig-utils/zig-js

Structured clone: secure relocation-stable object memoization

#859
Closed chris opened this 8 days ago ·
8 days ago

Parent: #493 Related: #482, #38, #39, #556, #858

Problem

The structured-clone serializer preserves graph identity with a default AutoHashMapUnmanaged(*Object, u32). JavaScript controls graph size, allocation order, and repeated references, so deterministic raw-pointer placement exposes collision-driven worst-case behavior. Raw addresses also are not the engine relocation identity contract: own-property getters run during serialization and can request collection, while managed object addresses may be rewritten by moving GC.

Scope

  • Replace the raw-pointer memo key with an exact tagged identity: zig-gc stable cell identity for managed objects and lifetime-stable address identity for arena/static objects.
  • Use a per-serialization secure keyed hash context without global state.
  • Keep first insertion failure-atomic: allocation or entropy failure must publish neither a context, a memo entry, nor an object id.
  • Preserve wire pre-order ids, cycles, aliases, DataCloneError behavior, frame limits, SAB token cleanup, and ordinary shallow behavior.
  • Reuse one runtime object-identity definition rather than creating divergent JSON and structured-clone contracts.

No-workaround rules

  • No disabling getters, callbacks, or moving GC.
  • No linear-only visited scan, address secrecy assumption, global visited mark, duplicated object serialization, reduced graph limit, or input blacklist.
  • No change to public structured-clone wire or JavaScript semantics.

Acceptance

  • Default raw-pointer memo is gone; managed identity survives relocation and address identity remains separately tagged.
  • A deterministic default-collision family disperses under a fixed nonzero keyed context.
  • Failed first insertion leaves context, memo, and next_id unpublished; retry succeeds exactly.
  • Cycles and repeated aliases remain exact through getter allocation/collection requests.
  • Focused Debug/TSan, full unit, exact structured-clone conformance, threadfuzz, public C API, and Home private-ABI gates pass with no regressions.
8 days ago

Landed as fix(structured-clone): secure object memoization (#859).

The serializer now uses one lazy per-invocation secure context over relocation-stable managed identities and separately tagged arena addresses. JSON and structured clone share the same runtime identity contract. First insertion remains failure-atomic, and wire pre-order ids, aliases, cycles, frame limits, DataCloneError behavior, and SAB cleanup remain exact.

Evidence:

  • Full units: 2,273 passed, 1 skipped, 0 failed, 0 leaked across 10 shards.
  • Structured clone: 12/12 passed in ReleaseSafe and TSan; the final legacy-collision/OOM witness passed in Debug and TSan.
  • Owned Worker/postMessage conformance: threadfuzz 400 programs, 0 failures.
  • Test262: not applicable; this checkout has no structuredClone subtree, so no zero-denominator claim was made.
  • Public C API: 117/117 complete.
  • Home private ABI: 447/447 implemented; 392/392 runtime shims passed in Debug, ReleaseSafe, and TSan.

Sign in to comment on this issue.