仮に「VMは安全だ」と思っていたとしても、境界はそこで終わらない
マイクロVMは、コンテナより一段深い隔離を与えるための仕組みだ。Firecracker の公式説明でも、KVM を使って軽量な仮想マシンを立て、不要なデバイスを削って攻撃面を小さくする思想が前面に出ている。Replit も自社の新しいサンドボックス基盤を microVM に寄せ、各サンドボックスを別カーネルにした理由をそこで説明している。
ただし、ここで安心しすぎると見落としがある。仮想マシンの外側にいるホストは、まだ一枚岩ではない。ゲストのパケット処理、仮想ネットワーク、メモリの持ち方、そしてホスト Linux のネットワークスタックがつながっている以上、「VM だからホストには触れない」は、設計の願望ではあっても証明ではない。今回の研究は、その隙間を正面から突いた。
Vercel の $1M Sandbox challenge では、2週間で 1,285 件の報告が集まり、そのうち最重要だったのが Linux カーネルの zero-day だったとされている。Vercel は、ゲストからホストメモリが漏れ、ホストのクラッシュやコード実行まで起きうると整理した。つまり問題は「VM の中で悪さをした」ことではなく、VM の中の入力がホストの信頼境界を越えたことにある。
研究者側の説明では、着目したのは hypervisor そのものではなく、ゲストが触れる Linux networking だった。pwn.ai はこの一連の脆弱性を PwnEscape と呼び、最初の段階で「checksum metadata」がホスト側の書き込み権限のように振る舞うことを示した。ここで問うべきなのは、なぜチェックサムの管理情報が、あとから packet bytes を書き換える力になり得たのか、という点だ。
チェックサムは計算結果ではなく、あとで書く約束でもある
Linux のチェックサム offload は、すべてをその場で計算しないための仕組みだ。CHECKSUM_PARTIAL という状態では、チェックサムが未完了のままパケットを運べる。skb->csum_start は計算を始める場所、skb->csum_offset は csum_start から結果の書き込み先までのオフセットを表す。平たく言えば、「どこから足し算を始め、どこへ答えを書くか」を後で実行するためのメタデータだ。
この手のメタデータは、普通なら便利なだけで終わる。NIC が代わりに計算してくれれば CPU 負荷は減るし、ソフトウェアのヘルパー skb_checksum_help() が補完することもある。だが重要なのは、これが単なる説明書きではなく、後続の書き込み権限を与える点にある。もし信用できない側がこの値を揺らせるなら、あとで書かれる場所そのものを揺らせる。
pwn.ai の説明では、問題の本質は「既に検証済みのパケット内容」に対して、後からチェックサム関連のメタデータが介入できてしまうことだった。Linux の側では、ヘッダの位置やフレームの見え方が段階ごとに変わる。Ethernet を含むフレームとして見ていた座標と、IPv4 として正規化された後の座標は同じではない。ここがずれると、入力時点では安全に見えた値が、別の局面では別の意味を持つ。
ここで従来の見方の弱さが出る。入力時に「十分後ろにある」と確認しただけでは足りない。チェックサムの完了が遅延するなら、その間に何が変わるかを見なければならない。pwn.ai は最初に 32 バイトのホストメモリ流出を観測し、その先に 64 バイト単位のホストカーネル書き込みへつなげたと述べている。32 から 64 へ倍増するだけでも、単なる情報漏えいでは終わらない匂いが出る。
「境界の検査が足りない」が、どこで壊れたのか
この話が厄介なのは、壊れた場所が派手な実装ではなく、普通のネットワーク経路にあることだ。pwn.ai は、__virtio_net_hdr_to_skb() の入力側の比較が、現在の skb->data 視点に対しては効いても、ネットワークヘッダ基準での安全性までは保証しなかったと説明している。つまり、見ていた座標系が違った。フレーム相対で正しくても、IPv4 相対ではまだ早い、ということが起きる。
このずれは、現場の感覚に置き換えるとわかりやすい。パケットを受け取る側は、リンク層の情報を剥がしながら上位層に渡す。だから「最初に見えた位置」が「最終的に意味を持つ位置」とは限らない。日本の現場でも、仮想 NIC やフィルタを挟む構成では、どの層の座標で判定したかが後で効いてくる。監査ログ上は同じ値に見えても、処理段階が違えば意味は変わる。
Vercel の公表では、研究者は microVM 内から送った特定のパケットで 3 種類の攻撃を示した。ホストメモリの漏えい、ホストのクラッシュ、ホストでのコード実行だ。しかもクラッシュとコード実行は、Vercel 自身の構成に近い KVM と Firecracker の環境で再現されたという。ここで見えてくるのは、特定ベンダーの設定ミスではなく、ホスト共有の Linux カーネルという土台そのものの危うさだ。
pwn.ai は、研究対象を Vercel 固有の欠陥とは切り分けている。pwn.ai は Vercel のサンドボックスに設定ミスは見当たらなかったと書き、Vercel も最も深刻な発見を upstream の Linux kernel の欠陥と説明した。ここで重要なのは、原因が「誰かの設定不備」ではないことだ。したがって、再発防止も一社だけで完結しない。実際に Vercel は影響を受けうる他のハイパーバイザー/サンドボックス事業者に通知し、研究者はカーネル保守側と修正パッチを作っている。
そこから先に見えるのは、VM ではなく実行中のホストプロセスだ
後半で詳しく触れる前に入口だけ言うと、この研究の本当の面白さは、漏れたホストメモリを「読む」だけで終わらなかった点にある。pwn.ai の続編では、その情報を使って Firecracker のホスト側プロセスを見つけ、vCPU の保存レジスタフレームを特定し、KVM から戻るタイミングを奪う流れが示される。つまり、ゲストから見えるのは単なる物理メモリではなく、実行中のスレッドの状態だ。
pwn.ai の続編の説明では、Firecracker の microVM ごとにホスト上に管理プロセスが 1 つあり、その中で vCPU ごとのスレッドが KVM_RUN を呼ぶ。pwn.ai はこの戻り際に保存される pt_regs フレームに狙いを定めた。レジスタフレームが見つかれば、再開先の命令ポインタやスタックポインタに手を伸ばせる。ここではもはや「VM を抜ける」というより、ホストの実行文脈を読み替えている。
Vercel は、この脆弱性が「host machine」をクラッシュさせ、さらに「full administrator privileges on the host」に届いたと要約している。ただし、pwn.ai 自身が、これは自前のホストでの証拠であり、どのベンダーの本番環境で root を取ったという主張でもない、と線を引いている。ここは丁寧に分けて読むべきだ。再現できたのは研究者が用意した KVM 環境(owned KVM fixture)でのホスト root 権限の補助プログラム(host-root helper)の実行で、本番環境への一般化とは別問題だからだ。
では、なぜチェックサムという地味な機能から、Firecracker のホスト側の実行線にまで届くのか。そのつながりは、単なる脆弱性の連鎖ではなく、Linux ネットワーキングと KVM の間にある「信頼してよいはずだったメタデータ」の扱いにある。どの値が、いつ、誰に対して書き込み権限を持つのか。そこをたどると、まだ説明していない核心が見えてくる。
👉 続き(核心はここから)は PaPoo で読めます: https://papoo.work/doc/dd3d4e522a5af662
