資安雷達 2026 年 10 月 21 日

2026-10-21 — wasmtime Cranelift 值索引溢位,惡意 Wasm 可逃出沙箱

primary=https://rustsec.org/advisories/RUSTSEC-2026-0380.html primary=https://github.com/bytecodealliance/wasmtime/security/advisories/GHSA-897f-g5gm-fmxm primary=https://github.com/bytecodealliance/wasmtime/pull/12613

wasmtime Cranelift 的 SSA 值索引位元打包溢位,惡意 Wasm 可誤編譯並逃出沙箱

RustSec / Bytecode Alliance · 2026-10-20

Cranelift 把 SSA 值索引塞進 24 位元欄位,函式夠大時索引會在 release build 靜默溢位,編譯器因此引用錯誤的值而產生錯誤機器碼;Wasmtime v43 已改為完整的 u32 索引並加上超限檢查。

這份通報為 RUSTSEC-2026-0380,對應 GHSA-897f-g5gm-fmxm,2026-10-19 由 Wasmtime 維護者發布,CVSS 9.9(Critical),GitHub 頁面標示「No known CVE」。

漏洞機制

Cranelift 的 IR 以 ValueDataPacked 儲存每個 SSA 值的定義,把標籤、型別與兩個值索引壓進一個 u64。依 PR #12613 的描述,舊配置是 tag:2 | type:14 | x:24 | y:24,也就是每個值索引只有 24 位元,但 Value 本身是 u32 實體索引。

當 Wasm 函式本體很大,或被刻意構造成使用大量 SSA 值,索引超出 24 位元就被截斷。release build 不會報錯,截斷後的索引指向另一個值,IR 因而引用錯誤對象。

通報的說法是,這會造成「arbitrary miscompilation」,攻擊者可藉此製造型別混淆(type confusion)或其他任意副作用,進而逃出沙箱。對應弱點為 CWE-197(數值截斷)與 CWE-843(型別混淆)。

原本的問題

Wasm 沙箱的安全性建立在「編譯器產生的機器碼忠實反映驗證過的 Wasm 語意」之上。驗證器只檢查輸入模組,不檢查 Cranelift 之後的輸出;一旦編譯器內部資料結構默默壞掉,被驗證過的模組也能變成越界讀寫的來源。

修補方式

舊:| tag:2 | type:14 | x:24 | y:24 |   (u64)
新:| tag:2 | type:14 | x:32 | y:32 |   (packed,10 bytes)

PR 把 x、y 擴成完整 32 位元,並用 packed 屬性讓結構維持 10 位元組。通報指出 v43 的 Cranelift 另加了超過上限時的檢查,所以超大函式會被拒絕,而不是被誤編譯。

受影響版本

  • 受影響:<36.0.19、>=37.0.0, <43.0.0
  • 已修補:36.0.19(36.x 的回補)與 >=43.0.0
  • 範圍:預設設定(使用 Cranelift 後端)、任何架構與平台

RustSec 的 patched 欄位為 >=36.0.19, <37.0.0 與 >=43.0.0,所以 37 到 42 版沒有對應的修補版本,只能升到 43 或更新。

影響範圍

風險最高的是替第三方執行 Wasm 的服務:外掛平台、edge function、多租戶 FaaS,以及把使用者提供的模組內嵌進 Wasmtime 的應用。攻擊向量為 Network、需要低權限,也就是能上傳或提交模組即可。

建議檢查以下幾點:

  • 用 cargo tree -i wasmtime 或 cargo audit 找出直接與傳遞依賴的 wasmtime 版本,注意被 vendored 進其他 crate 的情況。
  • 若鎖在 37 至 42,升到 43.0.0 以上;鎖在 36.x 的升到 36.0.19。

原始來源:RUSTSEC-2026-0380、GHSA-897f-g5gm-fmxm、wasmtime PR #12613


End of article
0
Would love your thoughts, please comment.x
()
x