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— DOMException의 stack trace에 대해 weak reference 정리 과정이 추가되었습니다. 이전에는 stack에 담긴 함수 참조가 GC 종료 시점에 정리되지 않았습니다. 그래서 이미 해제되어 다른 객체로 재할당된 JSCell을 읽을 수 있었고, use-after-free primitive에 해당하는 상황이 만들어졌습니다. - [WebRTC video frames] (OOB write)
dfe0d84—copyVideoFrameBuffer의 out-of-bounds write가 수정되었습니다. libyuv는 I420/I010 frame에서 UV chroma 크기를 짝수 경계로 올림 처리하는데, 목적지 buffer는 올림 이전의 원본 크기로 잡혀 있었습니다. 결과적으로 width나 height가 홀수인 frame에서 SharedMemory mapping을 넘어서는 기록이 발생했습니다. — 이후7072dd3에서 revert되었습니다. 수정본이 다시 올라오기 전까지 홀수 width에서의 OOB write는 main에 그대로 남아 있습니다. - [libwebrtc RTP AV1] (Integer truncation)
d7c8ef5— AV1 RTP packetizer의 signed 32-bit integer truncation이 수정되었습니다. OBU payload가 2 GiB 이상이면 크기 값이 음수로 wrap되었고, memcpy 단계에서 heap buffer overflow로 이어졌습니다. - [WebCore WebRTC RTP] (bounds check)
76f03b2—RTCEncodedVideoFrameMetadata.contributingSources의 갱신 경로가 제거되었습니다. 해당 코드는 CSRC 데이터를 복사할 때 bounds check를 수행하지 않았고, 이미 비활성 상태로 사용되지 않고 있었습니다. - [JSC WASM OMG tier-up] (miscompilation)
9a17cd1— SIMD를 사용하는 WASM callee를 SIMD를 쓰지 않는 root에 inline할 때, OMG tier-up이 해당 procedure를 SIMD 사용으로 표시하지 못했습니다. 그 결과 codegen 단계에서 register와 stack frame 크기가 잘못 계산되었습니다. 이번 패치로OMGIRGenerator가 SIMD 사용 여부를 판별하고 procedure state를 갱신하도록 변경되었습니다. - [ANGLE MSL translator] (bounds check bypass)
f05fd6d— MSL translator가 signed negate, -1에 의한 나눗셈, unsigned div/mod에 대해 UB-safe wrapper를 생략하고 있었습니다. 이때 Metal LLVM backend가ANGLE_int_clampbounds guard를 최적화로 제거할 수 있었습니다. WebGL2 페이지에서 조작된 shader를 구성하면 GPU device memory를 임의 위치로 인덱싱하는 것이 가능했습니다. - [JSC polymorphic call linking] (stale pointer write)
7920db1—CallLinkInfo에 대한 stale pointer 기록이 수정되었습니다.handleHostCall이후에는 polymorphic call linking을 건너뛰도록 변경되었는데, 이 함수는 watchpoint나 Proxy trap을 통해 JS를 재진입 실행할 수 있기 때문입니다. - [WebCore CSS] (Race condition, UAF)
b2c29f6—CSSPrimitiveValueserialization의 data race가 수정되었습니다. Worker thread가 FontFace descriptor를 직렬화하는 동안 main thread가 같은 작업을 수행하는 상황이 문제였습니다. 이때 HashMap rehash가 동시에 일어나면 한쪽 thread가 bucket pointer를 들고 있는 상태에서 backing buffer가 해제될 수 있었습니다. 이제 memoization은 main thread로만 제한됩니다. - [JSC DFG] (integer overflow / OOB)
03a07e4— DFG range optimization의 dependency 추적이 수정되었습니다. 해당 phase는 checked arithmetic을 unchecked로 전환하면서, 그 근거가 된 상위 check들을 고정해 두지 않았습니다. 그래서 DCE가 이 check들을 제거할 수 있었고, integer overflow와 typed array OOB 접근으로 이어졌습니다. - [JSC B3 optimizer] (type confusion)
7d86719— back-edge source가 여러 개인 loop에서BackwardsGraph가 잘못 구성되던 문제가 수정되었습니다. 이 상태에서는 B3의 LICM optimizer가 control dependency를 가진 값을 guard 위로 hoist할 수 있었습니다. WasmGC test case를 통해, 호환되지 않는 객체 타입에 대한 field 접근으로 이어질 가능성이 확인되었습니다. - [JSC DFG] (type confusion)
8283d4f— DFG의 Uint32ArrayGetByVal이 int32 speculation에도 불구하고 결과를 항상 double로 boxing하고 있었습니다. 그 결과 JSValue 표현이 어긋났습니다. 적절한 경우 int32로 boxing하도록 수정되어 type confusion이 차단되었습니다. - [WebCore Canvas2D] (hardening)
f0d5be8— Canvas 2D 텍스트 렌더링이 hardening되었습니다. state stack이 변경되는 동안FontProxy를 캐싱하지 않고, 사용할 때마다 다시 조회하도록 변경되었습니다. state Vector가 재할당되어 캐시된 pointer가 무효화되는 경우의 use-after-free를 막기 위한 조치입니다. - [WebCore WebRTC] (OOB write)
c18f11b— width나 height가 홀수인 I420/I010 frame에서copyVideoFrameBuffer의 out-of-bounds write가 수정되었습니다. libyuv의 chroma 올림 처리 때문에, 프로세스 간 video frame 공유에 쓰이는 SharedMemory buffer가 넘치면서 memory corruption이 가능했습니다. — 이후7072dd3에서 revert되었습니다. 수정본이 다시 올라오기 전까지 홀수 width에서의 OOB write는 main에 그대로 남아 있습니다. - [WebKit GPU process / RemoteRenderingBackend] (validator bypass)
d9bb3e4— DisplayList rendering mode 검증이allocateImageBuffer()안으로 옮겨져 모든 호출 지점을 포괄하게 되었습니다. 이전에는RemoteImageBufferSet::ensureBufferForDisplay()가remoteSnapshottingEnabledcapability check를 우회했습니다. - [WebKit NetworkProcess] (validator bypass)
e88c8b0— IPC 검증이 추가되었습니다. 장악된 web content process가 origin을 위조해 broadcast channel 메시지를 가로채는 경로를 차단하기 위한 변경입니다. - [WebCore cache storage] (race condition)
63ee8a1—CacheStorageConnection의 race condition이 수정되었습니다. main thread와 Worker에서cache.put()이 동시에 호출되면, opaque response 크기 map에 lock 없이 함께 접근할 수 있었습니다. 그 상태에서는 state 손상이나 crash로 이어질 위험이 있습니다. - [WebKit NetworkProcess] (sandbox bypass)
0748de3—registerInternalFileBlobURL에서 신뢰하기 어려운 sandbox extension 검증이 제거되었습니다. 이 검증에 의존하는 동안에는 장악된 WebProcess가 승인되지 않은 파일에 대해 blob URL을 등록할 수 있었습니다. 이제 접근 판단은 UIProcess가 확인한 허용 경로 목록만으로 이루어지며, image transcoding은 UIProcess IPC 쪽으로 이동했습니다. - [WebKit RemoteVideoDecoder] (race condition)
9ba6cb6— VideoDecoder callback에서m_timestampToDuration에 동시 접근하면서 발생하던 use-after-free가 수정되었습니다. JS thread와 LibWebRTCCodecs work queue 양쪽에서 안전하게 접근하도록 lock이 추가되었고,m_isClosed는 atomic으로 변경되었습니다. - [JSC PropertyCondition] (type confusion)
3387626— AbsencePropertyCondition이 reify되지 않은 static property table을 참조하지 않았습니다. 그래서 native static accessor가 가려진 경우 DFG가GetById를 잘못 컴파일했고, type confusion이 발생했습니다. - [WebCore DOM / Trusted Types] (UAF)
5549b36—trustedTypeCompliantString의 use-after-free가 수정되었습니다. 공격자가 제어하는 Trusted Types default policy callback이 호출 도중 iframe을 제거하면,processValueWithDefaultPolicy가ScriptExecutionContext를 해제할 수 있었습니다. - [WebCore graphics AVF] (race condition)
b17b55f— image decoder factory의 race condition이 수정되었습니다. main thread가 factory를 정리하는 동안 worker thread가 동시에 접근할 수 있었고, use-after-free로 이어졌습니다.ImageDecoderFactoryAVF는 동기화 없는 vector를 Lock으로 보호되는 singleton으로 대체했습니다. - [ANGLE ES3 format validation] (validator bypass)
9eeb617— ES3 format 검증이GL_DEPTH_COMPONENT32_OES와GL_UNSIGNED_INT_24_8조합을 잘못 허용하던 문제가 수정되었습니다. Metal backend에는 이 조합에 대한 converter가 없어서, 초기화되지 않은 heap 메모리가 GPU depth texture로 업로드되었습니다. - [JSC DFG] (type confusion, AI unsoundness)
cb05a60— DFG constant folding이 abstract interpreter state를 갱신하지 않고 남겨두던 문제가 수정되었습니다. 그 결과 실제로 도달 가능한 코드가 도달 불가능한 것으로 처리되었고, JIT 컴파일된 코드에서 type guard가 누락되었습니다. - [JSC B3 / PureCSE] (dangling pointer)
1d5c10e— PureCSE에 stale entry가 남던 버그가 수정되었습니다.specializeSelect()가 Check 값을 삭제하면서 CSE match map에서는 제거하지 않았기 때문입니다. 이후의 조회가 dangling pointer를 반환하면, compiler state가 손상되고 type 안전성이 깨진 JIT 출력이 생성될 수 있었습니다. - [WebCore ImageLoader] (UAF)
d40f4ef—ImageLoader의 이벤트 dispatch 과정에서 발생하는 use-after-free가 수정되었습니다. load handler는 picture element에서 image를 제거한 뒤showModalDialog로 중첩된 event loop를 돌릴 수 있습니다. 이때 dispatch 코드가 아직 실행 중인 상태에서 deref timer가 element를 해제할 수 있었습니다. - [UIProcess RemoteLayerTree] (UAF)
2df698f— UIProcessRemoteLayerTreeEventDispatcher의 scrolling thread timer에서 heap use-after-free가 수정되었습니다. main thread가 page close 정리를 수행하는 동안, callback이 이미 해제된TimerBasecontext를 읽을 수 있었습니다. 타이밍 제어가 가능하고 WebContent의 scroll/close 흐름에서 도달 가능한 경로입니다. 이번 수정으로 timer 소멸이 scrolling thread에서 순차 처리됩니다. - [WebCore HTMLMediaElement / WebAudio] (UAF)
55d9d90—MediaElementAudioSourceNode::provideInput의 use-after-free가 수정되었습니다. audio render thread가m_player를 사용하는 동안 main thread가 동기화 없이 이를 정리한 것이 원인이었습니다. 렌더링 도중 iframe detach 타이밍을 맞추면 exploit이 가능했으며, player invalidation을processLock으로 보호하는 방식으로 수정되었습니다. - [JSC Wasm OMG JIT] (type confusion)
9f07374— B3 Select specialization이 try block 안의 Wasm call patchpoint를 복제할 수 있었습니다. 그러면 두 호출 지점이 exception 복원용 stackmap을 공유하면서도 live value 배치는 서로 달라집니다. 이 경우 exception unwind 과정에서 타입이 맞지 않는 값이 복원될 가능성이 있었습니다. - [WebCore WebAudio] (UAF)
3e5b31e— WebAudio에서AudioParam에 대한 use-after-free가 수정되었습니다. thread 간 ref/deref race가 원인이었고, 일반적인 WebAudio graph 조작만으로 웹에서 도달 가능한 상태였습니다. - [WebCodecs] (integer underflow)
4fa207d—PlatformRawAudioData::copyTo()에서frameCount가 0일 때 integer underflow가 발생했습니다. 샘플 수 계산이0 - 1로 wrap되어 거대한 값이 되고, 이 값이 native copy에 buffer 길이로 전달되면서 out-of-bounds crash로 이어졌습니다. early return을 추가하는 방식으로 수정되었습니다.