This Week in WebKit — August 25 - September 1, 2026
Featured
The second one lives on the dead-code path, and BBQ trusts what it records. An arbitrary JS value walks into struct.get's fast path with no grooming and no cast in the way.
Pair that blind spot with recovery entries naming stack slots a later varargs call took over. An exit inside catch then hands the script an arguments object built from the wrong call.
Only out of a fast-memory function, and only into a BBQ callee that trusts what it inherits. Every bounds check there compares against a different instance's memory.
Downstream, ref.test finds its premise already proven and folds away. Upstream, the JS caller chooses the 64 bits that actually arrive — 0x4141414141414141, exactly.
Including the thread-local siblings another thread can be freeing mid-grow(). What comes back populates the pair every JIT bounds check compares against.
Security fixes
- Wasm block parameters keep the incoming type instead of the declared one
- `delegate` ends a `try` without widening its result to the block signature
Notable development
-
`ThreadSafeWeakPtr` torn dual-pointer replaced with lock-protected storage
bug WTF
-
Frame geometry sync consolidated into a single IPC payload
refactor WebKit Site Isolation
-
`WebEvent` and subclasses converted to ref-counted heap objects
refactor WebKit input events
-
Wasm `table.get` inlined into BBQ and OMG
optimization JSC WebAssembly JIT tiers
-
WebAuthn related-origin requests
feature WebKit WebAuthn
-
DFG stops clearing `NodeMustGenerate` on checked arithmetic
bug JSC DFG
-
Revert of the `copyVideoFrameBuffer` odd-width OOB fix
bug WebCore WebRTC
-
`JSString` gains a per-cell atom bit for concurrent profiling
bug JSC value profiling
-
Enable the offscreen web extension API
feature WebKit WebExtensions
Other security-relevant changes
- [JSC ErrorInstance] (UAF)
4d79cb1— Adds weak reference reconciliation for DOMException stack traces. Captured stack references to functions weren't reconciled at GC end, allowing reads of freed JSCells reallocated to other objects—a use-after-free primitive. - [WebRTC video frames] (OOB write)
dfe0d84— Fixed out-of-bounds write in copyVideoFrameBuffer: libyuv rounds UV chroma dimensions up to even boundaries for I420/I010 frames, but the destination buffer was sized with raw dimensions. Odd-width or odd-height frames would overrun the SharedMemory mapping. — subsequently reverted in7072dd3; the odd-width OOB write is live on main pending a corrected fix. - [libwebrtc RTP AV1] (Integer truncation)
d7c8ef5— Fixed signed 32-bit integer truncation in AV1 RTP packetizer where OBU payloads >= 2 GiB wrap size negative, causing heap buffer overflow in memcpy. - [WebCore WebRTC RTP] (bounds check)
76f03b2— Removed RTCEncodedVideoFrameMetadata.contributingSources update path; code lacked bounds checking when copying CSRC data and was disabled/unused. - [JSC WASM OMG tier-up] (miscompilation)
9a17cd1— OMG tier-up failed to mark procedures as using SIMD when inlining SIMD-using WASM callees into non-SIMD roots, causing incorrect register and stack-frame sizing during codegen. Patch ensures OMGIRGenerator detects SIMD usage and updates the procedure state accordingly. - [ANGLE MSL translator] (bounds check bypass)
f05fd6d— MSL translator omitted UB-safe wrappers for signed negate, division by -1, and unsigned div/mod, allowing Metal LLVM backend to optimize away ANGLE_int_clamp bounds guard. A WebGL2 page could craft a shader to index arbitrarily into GPU device memory. - [JSC polymorphic call linking] (stale pointer write)
7920db1— Fixed stale-pointer writes to CallLinkInfo by skipping polymorphic call linking after handleHostCall, which can execute reentrant JS via watchpoint or Proxy trap. - [WebCore CSS] (Race condition, UAF)
b2c29f6— Fixed data race in CSSPrimitiveValue serialization when Worker threads serialized FontFace descriptors concurrently with main thread; concurrent HashMap rehash could free backing buffer while another thread held bucket pointers. Memoization now restricted to main thread. - [JSC DFG] (integer overflow / OOB)
03a07e4— Fixed optimizer dependency tracking in DFG range optimization: the phase flipped checked arithmetic to unchecked without pinning upstream checks it relied on, allowing DCE to eliminate them and enable integer overflow with typed-array OOB access. - [JSC B3 optimizer] (type confusion)
7d86719— Fixed BackwardsGraph for loops with multiple back-edge sources, which allowed B3's LICM optimizer to hoist control-dependent values above guards. A WasmGC test case demonstrates this could enable field accesses on incompatible object types. - [JSC DFG] (type confusion)
8283d4f— DFG Uint32Array GetByVal was always boxing results as double despite int32 speculation, causing JSValue representation mismatch. Fixed to box as int32 when appropriate, preventing type confusion. - [WebCore Canvas2D] (hardening)
f0d5be8— Hardened Canvas 2D text rendering by re-fetching FontProxy on each use instead of caching across state-stack mutations; prevents use-after-free when the state Vector reallocates and invalidates cached pointers. - [WebCore WebRTC] (OOB write)
c18f11b— Fixed out-of-bounds write in copyVideoFrameBuffer for odd-width/height I420/I010 frames; libyuv's chroma rounding caused overflow of the SharedMemory buffer used for cross-process video frame sharing, enabling memory corruption. — subsequently reverted in7072dd3; the odd-width OOB write is live on main pending a corrected fix. - [WebKit GPU process / RemoteRenderingBackend] (validator bypass)
d9bb3e4— Moved DisplayList rendering mode validation into allocateImageBuffer() to cover all callers; previously RemoteImageBufferSet::ensureBufferForDisplay() bypassed the remoteSnapshottingEnabled capability check. - [WebKit NetworkProcess] (validator bypass)
e88c8b0— Added IPC validation to prevent compromised web content processes from spoofing origins to intercept broadcast channel messages. - [WebCore cache storage] (race condition)
63ee8a1— Fixed race condition in CacheStorageConnection where concurrent main thread and Worker cache.put() calls could simultaneously access the opaque-response size map without locking, risking state corruption or crashes. - [WebKit NetworkProcess] (sandbox bypass)
0748de3— Removed unreliable sandbox extension validation from registerInternalFileBlobURL that allowed compromised WebProcess to register blob URLs for unapproved files. Now gates access solely on UIProcess-confirmed allowed-path list with image transcoding moved to UIProcess IPC. - [WebKit RemoteVideoDecoder] (race condition)
9ba6cb6— Fixes use-after-free from concurrent access to m_timestampToDuration on VideoDecoder callbacks: added lock for thread-safe access from JS thread and LibWebRTCCodecs work queue, and made m_isClosed atomic. - [JSC PropertyCondition] (type confusion)
3387626— Absence PropertyCondition did not consult non-reified static property tables, allowing DFG to miscompile GetById when native static accessors were shadowed, causing type confusion. - [WebCore DOM / Trusted Types] (UAF)
5549b36— Fixes use-after-free in trustedTypeCompliantString where processValueWithDefaultPolicy could free ScriptExecutionContext when attacker-controlled Trusted Types default-policy callbacks remove the iframe mid-call. - [WebCore graphics AVF] (race condition)
b17b55f— Fixed a race condition in image decoder factory: worker threads could access factories simultaneously with main thread clearing them, causing use-after-free. ImageDecoderFactoryAVF replaces the unsynchronized vector with a Lock-guarded singleton. - [ANGLE ES3 format validation] (validator bypass)
9eeb617— Fixed ES3 format validation that incorrectly accepted GL_DEPTH_COMPONENT32_OES + GL_UNSIGNED_INT_24_8 combination. Metal backend lacks a converter for this pair, causing uninitialized heap memory to be uploaded into the GPU depth texture. - [JSC DFG] (type confusion, AI unsoundness)
cb05a60— Fixes DFG constant-folding that left stale abstract interpreter state, causing reachable code to be incorrectly treated as unreachable and missing type guards in JIT-compiled code. - [JSC B3 / PureCSE] (dangling pointer)
1d5c10e— Fixed PureCSE stale-entry bug where specializeSelect() deleted a Check value without removing it from the CSE match map, allowing later lookups to return a dangling pointer that could corrupt compiler state and produce type-unsafe JIT output. - [WebCore ImageLoader] (UAF)
d40f4ef— Fixed use-after-free in ImageLoader event dispatch where a load handler can remove an image from its picture element and spin a nested event loop via showModalDialog, allowing the deref timer to free the element while dispatch code still executes. - [UIProcess RemoteLayerTree] (UAF)
2df698f— Fixed heap-use-after-free in UIProcess RemoteLayerTreeEventDispatcher's scrolling-thread timer where callback could read freed TimerBase context during main-thread page-close teardown. Timing-controllable and reachable from WebContent scroll/close sequences. Fix serializes timer destruction on scrolling thread. - [WebCore HTMLMediaElement / WebAudio] (UAF)
55d9d90— Fixes use-after-free in MediaElementAudioSourceNode::provideInput caused by main thread clearing m_player without synchronization while the audio render thread accessed it. Exploitable via timing iframe detach mid-render; fixed by protecting player invalidation with processLock. - [JSC Wasm OMG JIT] (type confusion)
9f07374— B3 Select specialization could clone Wasm call patchpoints inside try blocks, allowing two call sites to share an exception-restoration stackmap with differing live-value layouts — could restore wrong-type values during exception unwind. - [WebCore WebAudio] (UAF)
3e5b31e— Fixed use-after-free of AudioParam in WebAudio caused by cross-thread ref/deref race; was web-reachable via normal WebAudio graph operations. - [WebCodecs] (integer underflow)
4fa207d— Integer underflow in PlatformRawAudioData::copyTo() when frameCount is zero; sample count calculation (0 - 1) wraps to huge value passed as buffer length to native copy, causing out-of-bounds crash; fixed with early return.