(BitVisor Summit 6 の懇親会が予想以上に盛り上がり,23時までいたら普通に日付変わってしまった...)
はじめに
本日,BitVisor Summit 6 Unsafe Nested Virtualization on Intel CPU というタイトルで発表しました.
端的に言うと,Intel CPU で,BitVisor 上で,VMM が動く,というものです.
発表内容の詳細は,スライドを見ていただければいいかなと思います.
この記事では,スライドに入っていない会場での議論や余談の内容を少し書こうかと思います.
発表スライド
AMD 対応版は 2 年前の BitVisor Summit 4 で,株式会社イーゲルの榮樂様によって発表されております.
https://www.bitvisor.org/summit4/slides/bitvisor-summit-4-2-eiraku.pdf
Unsafe Nested Virtualization の設計はこちらのスライドの方がわかりやすいかと思います.
今回の僕の発表はこの Intel 版実装についてとなります.
いつ Unsafe なのか?
誰だったか忘れましたが,実際にどういう場合に危ないのか? という質問を受けました.
色々あるとは思いますが,一番考えやすいのは L1 と L2 が共謀して L0 BitVisor のコードを破壊するというものです.
スライドにも書いておりますが,Unsafe Nested Virtualization では L1 物理アドレス = L0 物理アドレス なのをいいことに,L2 動作時に EPT に L1 VMM が作成した L2 物理 --> L1 物理の変換テーブルをそのままロードします.
これはアドレス変換に関しては特に問題ないのですが,L1 が作ったページテーブルによっては,L2 が L0 BitVisor の領域を読み書きすることができてしまいます.
つまり,L1 VMM が L0 BitVisor が居るであろうメモリ領域をマップしたページテーブルを作成し,これを L2 動作時にロードさせれば,L2 は EPT Violation などを起こさずに BitVisor の領域にアクセスできてしまいます.
会場でのデモ
会場では Unsafe Nested Virtualization のデモとして,KVM on BitVisor, VMWare Workstation Player on BitVisor の環境で Ubuntu 16.04 が起動するのをお見せしました.
デモの時にはお話しし忘れましたが,KVM は 1 vCPU, VMWare は 2 vCPU の VM を起動しました.
そして,Arch Linux on BitVisor on BitVisor も動作しました.
ただ,BitVisor が 2 つ動くと,dbgsh 叩いてもどっちの BitVisor が動作しているのかよくわからなかったですね...
仕組み上,おそらく dbgsh は L1 BitVisor のもののはずです.
L2 から L0 の VMMCALLを呼ぶ仕組みとかあっても面白いのかもしれません.
会場では,ものは試しと BitVisor on BitVisor on BitVisor も試してみましたが,さすがにこれは動きませんでしたね...
#VMEntry Failure ツライ & 考えられる用途
VM-x においては,VMEntry 時に設定した vCPU の状態の一部がおかしいと,エラーを返すようになっていますが,このエラーコードの情報量が少ないためにデバッグしづらいという話があります.
これを Nested Virtualization で何とかデバッグできないかという話があり,会場では Nested Virtualization は残念ながらあまり有効ではないだろうと答えました.
基本的には会場で答えた通りだと思いますが,もし Failure を出しているのがクローズドな VMM だと,割と原因究明に有効かもしれません.
というか,基本的にコードを弄れるものだとコードを弄った方がデバッグでは有用なことも多いかもしれませんが,クローズドな VMM の挙動を監視できる点が一ついいところなのかもしれません. (調べると怒られることもありそうですが)
VMCS Shadowing
実は,VT-x には Nested Virtualization を支援するための機能として VMCS Shadowing というものがあります.
これを使うと,L1 による VMREAD/VMWRITE を L0 への VMExit なしで CPU が勝手にやってくれるそうです.
それ以外にも機能があるかもしれませんが,ちょっとまだ追えてないです.
なぜこれを使ってないかというと,開発当初に実験用として使っていたマシンにこの機能がなかったからです...
(Core i5, i7 は大抵あると思いますが,オーバークロックモデル(型番の最後にKがつくモデル)にはなかったりします.)
ただ,VMCS Shadowing を使わなかったおかげで,VMREAD/VMWRITE をフックして色々できるというメリットもありそうです.
おわりに
思いつくまま会場で話したことなどを色々書いてみました.
質問や気づいた点,コメントなどがあれば,この記事や Twitter でコメントやリプライを送ってもらえれば,時間のある時にお返事できればと思います.