Parents: #493, #495 Related: #865
Problem
Bun__serializeJSValue returns a borrowed byte slice plus an opaque owner handle,
and Bun__SerializedScriptSlice__free authenticates release solely by that
handle. The process-global registry currently issues sequential integer tokens
and stores them in std.AutoHashMapUnmanaged(usize, ...).
A misbehaving native caller can predict another live serialized-script token and free its bytes while the rightful consumer still holds the borrowed slice. This turns a revision-pinned ownership boundary into cross-consumer release and a potential use-after-free. Arbitrary lookup tokens also retain predictable hash placement.
Required design
- Issue nonzero opaque owner capabilities from secure host entropy, with no counter, address, clock, constant, or deterministic fallback.
- Store owners in a separately seeded exact identity registry. Install its context only after the first backing allocation succeeds.
- Reject/resample zero and exact live-token collisions without replacing or releasing the existing owner.
- Token entropy, context entropy, or allocation failure must publish no handle or partial registry state; serialization must release its structured-clone references and byte allocation through the existing OOM path.
- Preserve exact bytes/layout, flags, SharedArrayBuffer reference release, duplicate/null/stale/forged free behavior, and thread-safe cross-context use.
- Reclaim empty registry backing/context after the last owner is consumed.
No-workaround rules
- No predictable fallback token/seed, address-derived capability, hash-only equality, leaked tombstones, lifetime cap, global lock removal, byte copy to hide ownership bugs, signature/layout change, skipped structured-clone release, or relaxed duplicate/stale handling.
Acceptance
- Deterministic zero/live-collision tests preserve the existing owner and install one unique nonzero capability.
- Legacy integer collisions disperse under separately keyed exact hashing; lookup/removal remain exact.
- Token/context entropy and first-allocation failures leave an empty, unseeded, retryable registry without leaking owned bytes/references.
- Duplicate/null/stale/forged and concurrent owner releases are inert and cannot release a different live slice.
- Focused serialization tests pass in Debug, ReleaseSafe, and TSan; full units, structured-clone/threadfuzz, public C API, and pinned Home/Bun ABI audits/runtime remain exact.