ReviewOS

zig-utils/zig-js

Atomics: securely seed the process-wide waiter table

#862
Closed chris opened this 9 days ago ·
9 days ago

Parent: #493 Related: #37, #490, #861

Problem

src/agent.zig stores the process-wide typed-array/Wasm waiter domains in std.AutoHashMapUnmanaged(WaitKey, *WaiterList). Zig hashes the public { SharedBufferStorage pointer, byte offset } bytes with fixed-seed Wyhash(0, ...).

JavaScript controls the number of live SharedArrayBuffer instances and the aligned byte offsets submitted through Atomics.wait, Atomics.waitAsync, and Atomics.notify. waitAsync can retain many domains without one OS thread per entry. A chosen collision family therefore amplifies lookup/insertion/removal inside the single process-wide waiters_mutex, delaying unrelated realms and Wasm wait/notify users as well as the attacker.

The mutex prevents engine data races but does not bound adversarial hash-table probe complexity.

Required design

  • Replace the auto-hash table with an exact WaitKey index whose bucket placement is keyed by process entropy.
  • Hash the storage identity and byte offset explicitly; never hash struct padding or weaken exact key equality.
  • Install the context lazily under the existing waiters_mutex, and publish no seed or partial index when the first table allocation fails.
  • Route insertion, lookup, removal, and test cleanup through the same installed context; no fixed fallback context is allowed after publication.
  • Preserve one FIFO list per exact domain, synchronous stack-ticket lifetimes, async ticket ownership/IDs, notify counts, teardown/interruption, and the shared typed-array/Wasm waiter domain exactly.
  • Do not add caps, sleeps, polling, input filtering, or semantic shortcuts.

Acceptance

  • A deterministic family colliding under the removed auto hash disperses under the keyed context while exact lookups/removals remain correct.
  • First-allocation failure leaves context, count, and capacity unpublished; retry succeeds exactly.
  • Existing waiter-table sync/async/FIFO/interruption/teardown tests pass in Debug, ReleaseSafe, and TSan.
  • Relevant Test262 Atomics wait/notify/waitAsync and Wasm atomic-wait gates show no regressions with a nonzero denominator.
  • Full sharded units, threadfuzz/no-GIL witnesses, and ABI boundaries pass.
  • Commit and closure evidence link exact commands/results.
9 days ago

Implemented and verified on main in fix(atomics): seed shared waiter domains (#862).

What changed:

  • Replaced the process-wide typed-array/Wasm waiter AutoHashMap with an exact WaitKey index keyed by process entropy.
  • Hashing encodes the stable storage identity and byte offset explicitly, never struct padding; equality remains exact pointer-plus-offset identity.
  • The existing waiters_mutex guards lazy context installation and every operation. First backing-allocation failure publishes neither context nor partial capacity, and entropy failure follows the existing fail-closed enqueue path without a clock/address/constant fallback.
  • FIFO ticket order, synchronous stack-ticket lifetime, async IDs/ownership/harvesting, notify counts, interruption, teardown, and the shared typed-array/Wasm waiter domain are unchanged.
  • Added 32 aligned offsets that all collide in the removed auto hash's low 10 bits; the keyed context disperses them while lookup/removal and failure/retry remain exact.

Evidence:

  • exact pushed commit waiter/Wasm cluster: 7/7 in Debug, 7/7 in ReleaseSafe, 7/7 in TSan; 0 leaks/races
  • Atomics.waitAsync unit coverage: 2/2, including cross-agent notify and retained async capacity
  • additional Wasm waiter growth/destruction lifetime: 1/1; total nonzero Wasm waiter coverage 2/2
  • full sharded units: 2,277 passed, 1 skipped, 0 failed, 0 leaked
  • exact-parent Test262 (19508195 -> 010b4cd7): test/built-ins/Atomics 390 -> 390, both 0 fail, 0 flips
  • no-GIL PR-249 typed-array path: atomics/ta-path-unchanged.js 1/1 passed
  • deterministic threadfuzz: 400 programs from seed 1, 0 failures
  • public C API: 117/117 declarations complete and public symbols present
  • Home private ABI: 447/447 implemented private symbols; 392/392 linked runtime matrix passed
  • formatting and diff checks pass

Sign in to comment on this issue.