Sampled mprotect write-guard for DOMWrapperWorld::m_wrappers corruption
DOMWrapperWorld::m_wrappers is the central hash map in the JS/DOM binding layer mapping DOM objects to their live Weak<JSObject> wrapper handles. Every time JS touches a DOM node, cacheWrapper inserts or updates an entry; the GC sweeps stale entries by calling JSC::WeakImpl::clear() during rehash, which dereferences a garbage address if the table is corrupt. This commit adds sampled instrumentation to catch the stray write.
Source/WebCore/bindings/js/DOMWrapperWorld.cpp
A new WrapperMapTableMalloc allocator places the hash table's backing on page-aligned mmap memory kept PROT_READ at rest; a WrapperMutationScope RAII guard briefly unlocks it to PROT_READ|WRITE during cacheWrapper/uncacheWrapper/clearWrappers. Enabled in roughly 1/64 processes at startup via weakRandomNumber, so a stray write outside a mutation scope faults immediately at the write site rather than corrupting memory that crashes much later.
Significance
This reveals an active, unresolved production heap corruption in WebKit's JS/DOM binding layer — the same garbage-pointer fingerprint appears in topologically unrelated hash tables (m_wrappers, CodeBlockSet), consistent with a freed object reused as a hash-table backing and then written by a dangling pointer.
Audit directions
During hash-table growth mid-mutation, the old backing is freed and a new one allocated; if m_wrappersTableBase is updated to the new backing before the old is released, the scope destructor's mprotect hits the new address while old pages are still live — verify the interleaving of noteTableBacking, forgetTableBacking, and mprotect during rehash. m_wrappersTableWritableDepth is a nested-scope refcount: an exception or a re-entrant cacheWrapper during a GC triggered inside a mutation could leave it positive while the page is read-only, or zero while writable, breaking the guarantee. Most importantly, the underlying corruption is unresolved — a stray write placing an attacker-controlled value into m_wrappers as a WeakImpl*, later dereferenced during GC sweep, is a potential controlled-read or type-confusion primitive worth investigating as an exploitable UAF.