Terry1234's blog

我們終會抵達各自的終點

0%

Maglev Float64ToTagged ConversionMode

幾天前我在分析 CVE-2025-9864,這篇主要是一些 murmur 和心得,看完後有思考了一下 bug pattern 的模式,然後嘗試找相似的漏洞
覺得可能會有其他用錯 ConversionMode 的地方
所以翻了一下 ConversionMode::kForceHeapNumber 與其他的 ConversionMode 嘗試理解他們的用途

source code 中有提到
Float64ToTagged's conversion mode is used to control whether integer floats should be converted to Smis or to HeapNumbers: kCanonicalizeSmi means that they can be converted to Smis, and otherwise they should remain HeapNumbers.
https://source.chromium.org/chromium/chromium/src/+/main:v8/src/compiler/turboshaft/turbolev-graph-builder.cc;l=5922?q=kCanonicalizeSmi&ss=chromium%2Fchromium%2Fsrc:v8%2F

kCanonicalizeSmi 會去看當前 value 能不能被 smi 表示,可以的話就會產出 smi 相關的 node,否則用 HeapNumber
而 kForceHeapNumber 則一律用 Heap Number
CVE-2025-9864 的成因是沒有考慮到建圖時的用來省略 Write Barrier() 的一項機制,一律使用 kForceHeapNumber 來 allocate 出 Heap Number,導致還在使用中、需要 Write Barrier 的 Heap Number 被 GC 回收形成 UAF

Write Barrier 是一項用來幫助 V8 Garbage Collection 的機制,細節可以看官方文件
https://chromium.googlesource.com/v8/v8.git/+/refs/tags/13.1.147/src/heap/WRITE_BARRIER.md

看完後想到 kForceHeapNumber 會不會有其他問題(e.g. 因為 Maglev 有非常多的 Optimize 機制,開發者可能會沒考慮到這些機制,一律使用 kForceHeapNumber 導致一些奇怪的問題,例如這次的 UAF)
所以就去翻了一下 kForceHeapNumber 在哪裡被用到,發現他在 src/maglev/maglev-inlining.cc 有被用到
用 switch 判斷 ValueRepresentation 來決定怎麼新增 IR 的方式跟 CVE-2025-9864 出問題的地方非常相似
CVE-2025-9864 Patch: https://chromium-review.googlesource.com/c/v8/v8/+/6787941
我懷疑這個地方可能有問題所以打算讀 code 做分析,當時大概是 9/8 晚上
讀到一半覺得太累了去睡覺,醒來後發現 V8 發了一個 Commit 對這個地方做 Patch

Patch : https://chromium-review.googlesource.com/c/v8/v8/+/6917249
對應到的 Issue 是 https://issues.chromium.org/issues/443476912
(V8 的 commit 如果是在修漏洞的話,Commit Message 中會有 Bug ID。雖然沒辦法看到 Issue 細節,但可以用 diff 分析漏洞成因)
等 Issue 開後想看一下什麼時候回報的,疑似差點撿到 V8 的洞 XD

以後有洞一定盡快看完然後找 Variant XD

其他用 kForceHeapNumber 的地方都被修掉了,這個 bug Pattern 應該不會再出現了XD