コンパイラーの誤コンパイルによるWasmtimeサンドボックス脱出(CVE-2026-115889)
CVE-2026-115889は、クリティカルなWasmtimeのサンドボックス脱出です。Craneliftがインデックスを24ビットのフィールドに詰め込み、細工したモジュールがそれをオーバーフローさせます。36.0.19と43.0.0で修正済みです。
要点
- Wasmtimeは独自のコンパイラーバックエンドCraneliftでWebAssemblyをコンパイルします。コンパイラーの中間表現では、各値レコードが命令、ブロック、値のインデックスを64ビットワードの24ビット部分に格納し、デバッグビルドでだけパニックするチェックで守っていました。
- いずれかのインデックスを2^24 - 1、約1,670万を超えるまで増やすWasm関数は、リリースビルドで24ビットフィールドをオーバーフローさせます。実際に巨大な関数でも、数を増やすよう細工した関数でも起こります。値は誤った命令、ブロック、値を参照し、コンパイラーは壊れたデータから機械語を生成します。結果として型混同が生じ、サンドボックス脱出につながり得ます。
- Bytecode Allianceの評価はクリティカル、CVSS v3.1 9.9で、全アーキテクチャのデフォルトCraneliftバックエンドが影響します。メイン系列はWasmtime 43.0.0(2026年3月)から修正済みです。36.x保守系列は、アドバイザリと同じ2026年10月19日公開の36.0.19でバックポートされました。
- 36.xでは36.0.19以降へ更新してください。メイン系列の43.0.0が直すのはCVE-2026-115889だけです。下記3件すべてに対応するには48.0.7以降、49系列では49.0.4以降を使います。2026年10月24日時点で実環境の悪用は確認されていません。
- 同じ10月の期間に2件の関連する脱出があります。CVE-2026-115893では、約256,000を超える対象を持つ
br_tableがaarch64で攻撃者指定のオフセットへジャンプし、36.0.19、48.0.7、49.0.4で修正されています。GHSA-m9f7-9w4p-gv38はmacOSとFreeBSDでシンボリックリンクの名前変更により任意のホストディレクトリをゲスト内へ移せる問題で、36.0.18、48.0.6、49.0.3で修正されています。
影響を受けるか
次の条件をすべて満たす場合に影響を受けます。
- Wasmtimeまたはそれを組み込んだ製品で、デフォルトのCraneliftバックエンドを使う
- 36.x保守系列では36.0.19未満、メイン系列では37.0.0~42.x
- ゲストのWasmモジュールが完全には信頼されていない。テナント、ユーザー、その他、信頼する代わりにコードを閉じ込める相手からゲストを受け取る
アドバイザリは、どのアーキテクチャ・プラットフォームでも、Craneliftを使うデフォルト設定のWasmtimeエンジンが、細工したWasmモジュールによってサンドボックス脱出を受け得ると明記しています。信頼された自社モジュールだけを動かすエンジンは、この攻撃にさらされません。
2026年10月のアドバイザリ群には影響範囲の違う脱出がさらに2件あるため、表では個別に示します。
| 欠陥 | 影響を受けるバージョン | 修正バージョン |
|---|---|---|
| CVE-2026-115889、全アーキテクチャ | 36.x:36.0.19未満。メイン系列:37.0.0 – 42.x | 36.0.19と43.0.0(メイン系列、2026年3月) |
| CVE-2026-115893、aarch64のみ | 36.x:36.0.19未満。メイン系列:37.0.0 – 48.0.6、49.0.0 – 49.0.3 | 36.0.19、48.0.7、49.0.4(すべて2026年10月19日公開) |
| GHSA-m9f7-9w4p-gv38、macOSとFreeBSDのwasmtime-wasi | 36.x:36.0.17以前。メイン系列:37.0.0 – 48.0.5、49.0.0 – 49.0.2 | 36.0.18、48.0.6、49.0.3(すべて2026年10月14日公開) |
aarch64のアドバイザリは、v1.0より前の2020年の初期対応までさかのぼり、aarch64をサポートする全WasmtimeがCVE-2026-115893の影響を受けるとしています。ファイルシステムの問題には、ゲストがサンドボックス内ディレクトリへ書けることと、ホストがmacOSかFreeBSDであることが必要です。LinuxとWindowsのrenameatは末尾スラッシュ付きシンボリックリンクをたどらず、影響しません。
使用バージョンを確認します。
# CLI version
wasmtime --version
# Rust dependency tree
cargo tree -i wasmtime -e features | head
cargo tree --depth 1 | grep wasmtime
# Docker image check
docker run --rm <your-image> wasmtime --version
WasmtimeはCLIより組み込みで使われることが多いため、プラットフォームの依存関係ツリーを確認してください。サーバーレスやプラグイン基盤は、バージョンを固定していることがよくあります。
修正方法
Wasmtimeを更新します。3件をまとめて解消する最小バージョンは、36.xで36.0.19、48系列で48.0.7、49系列で49.0.4です。
# Rust, 36.x maintenance line
cargo update -p wasmtime --precise 36.0.19
# Rust, 48 line
cargo update -p wasmtime --precise 48.0.7
# Rust, 49 line
cargo update -p wasmtime --precise 49.0.4
# CLI install script (installs the latest release)
curl https://wasmtime.dev/install.sh -sSf | bash
43.0.0が修正するのはCVE-2026-115889だけです。43.0.0~48.0.6と49.0.0~49.0.3にはaarch64のbr_table脱出が残り、43.0.0~48.0.5と49.0.0~49.0.2にはファイルシステム脱出が残ります。
アドバイザリに回避策はありません。異常に大きい関数本体をコンパイル前に拒否すれば、到達する入力を絞れますが、修正ではありません。アドバイザリは巨大な本体とは別に、多数のSSA値を使うよう細工した関数を挙げており、バイト数上限は信頼できる境界ではありません。エンジン更新を修復、上限は一時対策として扱ってください。
OstorlabでRustリポジトリとコンテナーイメージをスキャンし、wasmtimeを36.0.19、48.0.7、49.0.4より古い版に固定した全ビルドを確認してください。
根本原因
Craneliftの中間表現は、各SSA値をValueDataPackedレコードで追跡します。64ビットを維持するため、2ビットのタグ、14ビットの型、xとyという2つの24ビットフィールドを一つのワードに格納していました。
yは定義元命令のインデックス、ブロックのインデックス、エイリアス元の値のインデックスを持ち、関数が大きくなるほど増えます。命令結果やブロック引数の場合、xは出力番号や引数番号だけなので小さいままです。最適化器が作るunionノードでは、両方が値のインデックスです。影響ソースの配置です。
// cranelift/codegen/src/ir/dfg.rs (before the fix)
// | tag:2 | type:14 | x:24 | y:24 |
//
// Inst 00 ty inst output inst index
// Param 01 ty blockparam num block index
// Alias 10 ty 0 value index
// Union 11 ty first value second value
格納用ヘルパーは、リリースビルドでは消えるデバッグアサーションだけで幅を守っていました。
// cranelift/codegen/src/ir/dfg.rs (before the fix)
fn encode_narrow_field(x: u32, bits: u8) -> u32 {
let max = (1 << bits) - 1;
if x == 0xffff_ffff {
max
} else {
debug_assert!(
x < max,
"{x} does not fit into {bits} bits (must be less than {max} to \
allow for a 0xffffffff sentinel)"
);
x
}
}
アサーションが消えると、encode_narrow_fieldはインデックスをそのまま返します。格納コードはマスクせずシフトしてORするため、24ビットを超える部分が隣のフィールドにあふれます。読み戻しでは各フィールドを24ビットにマスクします。yの命令インデックス2^24は0として読まれ、まったく別の命令になり、xも壊します。
一文で言えば、コンパイラーのデータ構造が実体のインデックスを狭すぎるフィールドへ保存し、唯一のオーバーフローチェックがリリースビルドで消えたため、十分な値を持つ関数がコード生成前にコンパイラー自身の値と定義の対応を壊しました。
結果は攻撃者が影響できる誤コンパイルです。誤った定義元命令を主張するValueは、その命令の結果型と意味を引き継ぎます。コンパイラーは、ある演算の出力を別の型として消費する機械語を出力します。ゲスト内のコンパイル済みコードに型混同が生じ、Wasmtimeが守るサンドボックスが破られます。
悪用の仕組み
攻撃者が、Craneliftの命令、ブロック、値のインデックスを2^24 - 1より大きくする関数を一つ含むWasmモジュールを送ります。リリースビルドでは静かに周回し、誤コンパイルされた型混同コードがホスト権限で動きます。2026年10月24日時点で公開PoCや実環境の悪用はありません。アドバイザリとパッチからわかる経路です。
- テナントによるコード配備、ユーザーによるプラグインアップロードなど、ゲスト作成者である攻撃者がエンジンへWasmモジュールを提供できます。これがCVSS v3.1で必要権限が低とされる理由です。
- モジュール内の一つの関数が、命令、ブロック、値のインデックスを2^24から1を引いた約1,670万より大きくします。アドバイザリは、非常に大きな関数本体と、多数のSSA値を使うよう細工した関数の2形態を示します。
- Cranelift IRへの変換と最適化中にインデックスが24ビットフィールドを超えます。リリースビルドではパニックせず、レコードが静かに別のインデックスを指します。
- 最適化器とバックエンドが壊れた対応を読みます。値が誤った型の誤った定義へ解決され、検証器が見ていない演算を機械語が行います。例えば整数のビットが参照や異なる型の値として再解釈されます。
- 攻撃者はゲスト内の型混同コードでWasm線形メモリ境界外を読み書きしたり、サンドボックスが隠すべきホスト機構に到達したりします。ホストプロセス権限で動くサンドボックス脱出です。
攻撃全体は一つのコンパイル済みモジュールです。ホストAPIの誤用、エンジン設定ミス、2つ目の脆弱性は不要です。
細工されたモジュールがオーバーフローから脱出へ進む流れ
Wasm関数を入力"] --> B["Craneliftが一つのu64の
24ビットフィールドへ格納"] B --> C["リリースビルドにはデバッグ用チェックがなく
無警告でオーバーフロー"] C --> D["値レコードが誤った
命令やブロックを参照"] D --> E["バックエンドが壊れた型情報から
コードを出力"] E --> F["ゲスト内の型混同が
Wasmサンドボックスを破る"]
不備のあるチェックはCです。唯一のオーバーフロー防止がリリースビルドにはありません。
攻撃者に可能なこと
WebAssemblyのサンドボックスを脱出し、ホストプロセスの権限でコードを実行できます。Wasmtimeはゲストコードを信頼しないモデルのため、脱出とはゲストがホストメモリ、ホストAPI、プロセスの能力へ直接届くことです。CVSS v3.1ベクトルAV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:Hはスコープ変更と機密性・完全性・可用性への高い影響を示し、ゲストがホストを侵害する状況に対応します。
必要条件です。
- 全アーキテクチャで、デフォルトのCraneliftバックエンドを使うリリースビルドのWasmtime
- 36.xでは36.0.19未満、または37.0.0~42.x
- 攻撃者のコードをエンジンが実際にコンパイルする。信頼済みモジュールだけを事前コンパイルするエンジンや別バックエンドは、実証された経路の対象外
関連する2つのサンドボックス脱出
同じ10月の期間には、2026年10月19日と14日に公開された脱出がさらに2件あり、どちらもCVE-2026-115889とは修正バージョンが異なります。
CVE-2026-115893:大きなbr_tableがaarch64で脱出する仕組み
aarch64バックエンドでは、単一のbr_tableに約256,000を超える対象を持つWasmモジュールが、不正な分岐先の条件分岐へコンパイルされます。モジュールが制御するオフセットの任意コードへジャンプでき、アドバイザリは任意のサンドボックス脱出に至るとしています。
v1.0以前の2020年の初期対応まで、aarch64対応の全Wasmtimeが影響します。2026年10月19日の36.0.19、48.0.7、49.0.4で修正されました。メイン系列43.0.0~48.0.6はCVE-2026-115889を直していますが、本件は残ります。
GHSA-m9f7-9w4p-gv38:シンボリックリンクの名前変更によるファイルシステム脱出
wasmtime-wasiクレートでは、ゲストがプロセスから到達できる任意のホストディレクトリを自分のサンドボックスへ移し、読み書きできました。
名前変更時、wasmtime-wasiは親ディレクトリを解決するため、元パスの末尾スラッシュを削除し、renameat前に付け直します。ゲストがsymlink("../outside", "up")など外を指す相対シンボリックリンクを作り、"up/"をサンドボックス内へ移すと、ホストカーネルがリンクをたどり、外のディレクトリを中へ移します。以前のGHSA-vqjp-4c8c-hfggの修正は、開く処理を変えただけで名前変更は変えていませんでした。
macOSとFreeBSDが影響し、LinuxとWindowsはrenameatが末尾スラッシュ付きリンクをたどらないため影響しません。ゲストには内部ディレクトリへの書き込み権限が必要です。2026年10月14日の36.0.18、48.0.6、49.0.3で修正されています。既知の回避策はなく、CVEもありません。
どちらの関連アドバイザリにも実環境の悪用報告はありません。
修正が機能する理由
修正は狭いフィールドをなくし、xとyを完全なu32インデックスへ変えます。関数サイズによって別の定義へ周回しなくなります。メイン系列ではプルリクエスト#12613(2026年2月18日マージ、Wasmtime 43.0.0に搭載)が、格納したu64を次に置き換えました。
// cranelift/codegen/src/ir/dfg.rs (after the fix)
-struct ValueDataPacked(u64);
+#[repr(Rust, packed)]
+struct ValueDataPacked {
+ x: u32,
+ y: u32,
+ flags_and_type: u16,
}
配置コメントはx:24 | y:24からx:32 | y:32へ変わります。両フィールドはu32の全範囲を保持し、狭める必要がないためencode_narrow_fieldとdecode_narrow_fieldは削除されます。レコードは8から10バイトへ増えますが、PRのベンチマークではコンパイル時間が3~5パーセント短縮しました。
36.0.19のバックポートであるプルリクエスト#14818は、同じ変更を保守系列へ運びます。同じリリースには、wasi-httpの競合するcontent-length(GHSA-r8xh-cgf7-392j)と、aarch64のbr_table分岐先(CVE-2026-115893、GHSA-mghf-wjfp-p5xm)という他の2件の修正も含まれます。
この構造のこの種のオーバーフローに対する修正は完全です。値は狭める処理を通らなくなり、関数サイズで対応を壊せなくなります。アドバイザリは、Craneliftが完全なu32を使い、その上限超過もチェックするようになったため、u32上限でも無警告にならないと補足しています。
侵害されたかを確認する方法
このアドバイザリには侵害指標がありません。誤コンパイルによる脱出の公開シグネチャやIOCはなく、悪用も確認されていません。影響エンジンで信頼できないゲストを動かしていて監査したい場合は、次を確認します。
- モジュールハッシュやテナントのアップロード履歴を記録しているなら、誰が何をコンパイルしたかをレビュー。この不具合を狙うモジュールは、バイト数に対してSSA値が異常に多い一つの関数
- ゲスト側の異常報告、ホストのクラッシュとして現れる境界外読み取り、検証器からはあり得ない動作を、ゲストだけでなくホストプロセスを調べる理由として扱う
- 侵害が疑われればホストプロセス全体を侵害済みとし、保持する全シークレットをローテーションし、正常と確認できる状態から再構築。脱出したゲストコードはホスト権限で動くため
経緯
- 2026年2月18日:プルリクエスト#12613「Cranelift: update ValueDataPacked to support full Value range」をメイン系列へマージ。
- 2026年3月20日:Wasmtime 43.0.0が全幅のエンコードを搭載。
- 2026年10月14日:Bytecode Allianceが、macOSとFreeBSDで末尾スラッシュ付きリンクの名前変更を使うwasmtime-wasi脱出GHSA-m9f7-9w4p-gv38を公開し、36.0.18、48.0.6、49.0.3で修正。
- 2026年10月19日:報告者jaydnsへ謝辞。Bytecode AllianceがGHSA-897f-g5gm-fmxmと関連GHSA-mghf-wjfp-p5xm(CVE-2026-115893、aarch64の
br_table脱出)を公開し、両バックポートを含む36.0.19と、br_tableを修正する48.0.7、49.0.4を公開。 - 2026年10月23日:CVE-2026-115889公開。
- 2026年10月24日:本記事を公開。3件とも実環境の悪用は確認されておらず、CISA KEVカタログにも未登録。
- 2026年10月26日:関連するGHSA-mghf-wjfp-p5xm(CVE-2026-115893)とGHSA-m9f7-9w4p-gv38を追記。
よくある質問
メイン系列がアドバイザリの数か月前に修正された理由は?
2月のu32全幅化は関数本体サイズの制限をなくす変更で、正確性の改善として行われ、公開セキュリティ修正ではありませんでした。旧エンコードのセキュリティ影響は後で報告されました。10月のアドバイザリは、v43以降は影響せず、36.0.19が保守系列へバックポートするという両事実を記録しています。
一つの関数に1,670万命令なければ安全か?
いいえ。閾値は値レコードに格納する命令、ブロック、値の各インデックスで、それぞれ約1,670万です。値のインデックスはSSA値の数とともに増え、アドバイザリは多数のSSA値を使うよう細工した関数も挙げています。そのため、バイト数制限は確実な境界ではありません。アップグレードしてください。
デバッグビルドも影響を受けるか?
いいえ。デバッグビルドではdebug_assert!が働き、対応を壊さずコンパイルが終了します。本番エンジンはリリースビルドなので、アドバイザリはその動作を対象とします。
Winchバックエンドや事前コンパイル済みモジュールも影響を受けるか?
アドバイザリの対象はデフォルトのCraneliftです。事前コンパイル済みモジュールを実行するエンジンは、破損が起こるコンパイル段階を飛ばします。ただし、他のバックエンドや事前コンパイル経路をアドバイザリが除外していないため、更新すべきです。
Wasmtimeはどれほど普及しているか?
wasmtimeクレートのcrates.ioダウンロード数は累計41,373,089、直近90日で11,809,615です。サードパーティコードを閉じ込めるサーバーレスやプラグイン基盤のエンジンであり、この欠陥はまさにその境界を越えます。
モジュール制限を設けるWasmtime基盤も影響するか?
組み込みエンジンが影響版なら、はい。制限は入力を狭めますが修正の一部ではありません。上限に頼らずエンジンを更新してください。
43.0.0以降へ更新すれば3件とも解消するか?
いいえ。メイン系列のCVE-2026-115889は43.0.0から修正済みですが、ファイルシステム脱出の初修正は48.0.6(49系列は49.0.3)、aarch64のbr_table脱出は48.0.7(49系列は49.0.4)です。36.x保守系列では36.0.19が3件すべてを解消します。
参考資料
- Bytecode AllianceのアドバイザリGHSA-897f-g5gm-fmxm:https://github.com/bytecodealliance/wasmtime/security/advisories/GHSA-897f-g5gm-fmxm (2026年10月24日確認)
- Bytecode AllianceのGHSA-mghf-wjfp-p5xm、CVE-2026-115893。aarch64の
br_table脱出、クリティカル、CVSS v3.1 9.9、36.0.19、48.0.7、49.0.4で修正:https://github.com/bytecodealliance/wasmtime/security/advisories/GHSA-mghf-wjfp-p5xm (2026年10月26日確認) - Bytecode AllianceのGHSA-m9f7-9w4p-gv38。macOSとFreeBSDで末尾スラッシュ付きリンクの名前変更を使うwasmtime-wasi脱出。重大度高、CVEなし、36.0.18、48.0.6、49.0.3で修正:https://github.com/bytecodealliance/wasmtime/security/advisories/GHSA-m9f7-9w4p-gv38 (2026年10月26日確認)
- CVE-2026-115889レコード(CVSS v3.1 9.9、CWE-197、CWE-843、影響範囲):https://cveawg.mitre.org/api/cve/CVE-2026-115889 (2026年10月24日確認)
- 2026年2月18日にマージされたメイン系列の修正PR #12613:https://github.com/bytecodealliance/wasmtime/pull/12613 (2026年10月24日確認)
- 同じ36.0.19バックポートで修正された、wasi-httpのcontent-length競合に関するGHSA-r8xh-cgf7-392j:https://github.com/bytecodealliance/wasmtime/security/advisories/GHSA-r8xh-cgf7-392j (2026年10月27日確認)
- 36.xへのバックポートPR #14818:https://github.com/bytecodealliance/wasmtime/pull/14818 (2026年10月24日確認)
- Wasmtime 36.0.19リリース(2026年10月19日公開):https://github.com/bytecodealliance/wasmtime/releases/tag/v36.0.19 (2026年10月24日確認)
- Wasmtime 43.0.0リリース(2026年3月20日公開):https://github.com/bytecodealliance/wasmtime/releases/tag/v43.0.0 (2026年10月24日確認)
- 36.x系列の脆弱なdfg.rs(ValueDataPackedエンコード):https://github.com/bytecodealliance/wasmtime/blob/v36.0.18/cranelift/codegen/src/ir/dfg.rs (2026年10月24日確認)
- wasmtimeのcrates.ioダウンロード数(累計41,373,089、直近90日で11,809,615):https://crates.io/api/v1/crates/wasmtime (2026年10月24日確認)