Pitfalls in VM Implementation on CHERI: Lessons from Porting CRuby

本論文は、CRuby のポート事例と既存研究の調査に基づき、従来のアーキテクチャにおける C 言語の未定義動作を前提とした VM 実装の慣習が CHERI の厳格なメモリ安全性モデルと衝突して生じる具体的な落とし穴を分類・解説し、その回避策と影響について論じています。

Hanhaotian Liu (University of Tokyo, Japan), Tetsuro Yamazaki (University of Tokyo, Japan), Tomoharu Ugawa (University of Tokyo, Japan)

公開日 Mon, 09 Ma
📖 1 分で読めます☕ さくっと読める

Each language version is independently generated for its own context, not a direct translation.

論文の解説:CHERI という「新しい家」に、古い「Ruby の家」を移す話

この論文は、**「CHERI(チェリ)」という新しい、非常に安全なコンピューター技術を使って、有名なプログラミング言語「Ruby(ルビィ)」**のエンジン(VM)を動かそうとしたときに、どんな落とし穴にハマったのか、そしてどう乗り越えたかをまとめたものです。

まるで、**「古い木造家屋(Ruby)を、最新の耐震・防犯システムが完備された新しいコンクリート製マンション(CHERI)に移築する」**ような作業だと想像してください。


1. 背景:なぜ「CHERI」が必要なのか?

これまでのコンピューターは、メモリの場所を指し示す「ポインター(住所)」を、ただの数字として扱ってきました。しかし、これには「隣の家を間違えて入っちゃう」「消えた家の鍵で無理やり開けようとする」といったセキュリティの穴がありました。

CHERIは、この問題を解決するために生まれた新しい技術です。

  • 従来のポインター:「住所(数字)」だけ。
  • CHERI の能力(Capability):「住所」+「許可証(どこまで触っていいか)」+「有効期限(いつまで使えるか)」+「本物証明(偽物ではないか)」がセットになった**「万能鍵」**のようなものです。

これにより、メモリの安全性が劇的に向上しますが、「万能鍵」のルールは厳格です。古い家の住人(Ruby のコード)が、新しいマンションのルールに従わないと、ドアが開かなくなったり、警報が鳴ったりしてしまいます。


2. 移住(ポート)作業で見つかった 6 つの「落とし穴」

著者たちは、Ruby のエンジン(CRuby)を CHERI 向けに改造する過程で、以下のような「古い常識が通用しない」問題に直面しました。

① 「仮の住所」から「本物の住所」を作るな

  • 状況:Ruby は、スタック(一時的な作業場)の一番上にある変数の住所を「スタックの端」として使っていました。
  • 問題:CHERI では、変数ごとの「万能鍵」には、その変数だけの狭い範囲しか許可されていません。そこから「スタック全体」を指す鍵を作ろうとすると、**「許可範囲外」**としてエラーになります。
  • 解決策:最初から「スタック全体」をカバーできる「親鍵(スーパーキー)」を持っておき、そこから必要な鍵を派生させるようにしました。

② 「数字」を無理やり「鍵」に変えるな

  • 状況:Ruby のガベージコレクション(不要なメモリの掃除)は、「スタックにある数字が、たまたま住所っぽければ、それは鍵だ!」と判断して中身を確認します(曖昧なポインター)。
  • 問題:CHERI では、単なる数字を鍵に変えても、「本物証明(タグ)」がついていないため、開けようとした瞬間に警報(エラー)が鳴ります。
  • 解決策:「住所っぽいか」ではなく、**「本物の鍵の証明(タグ)がついているか」**を確認するようにルールを変えました。これにより、無駄な掃除を減らすこともできました。

③ 「同じ場所」に拡張して住み続けられるとは限らない

  • 状況:メモリを拡張する際、古いコードは「同じ住所の鍵を使いまわして、範囲を広げれば OK」と考えていました。
  • 問題:CHERI では、メモリを拡張すると、新しい鍵は「新しい範囲」しか持たず、古い鍵はそのままでは使えなくなります。
  • 解決策:拡張されたら、必ず**「新しい鍵」に持ち替える**ようにコードを書き換えました。

④ 「整数の隙間」を埋めるな

  • 状況:Ruby は、整数の「隙間(パディングビット)」をデータとして使ったり、ビット操作で細工したりしていました。
  • 問題:CHERI の「万能鍵(整数型)」は、上 64 ビットに「許可証などのメタデータ」が入っており、下 64 ビットだけが実際の数字です。「隙間」を操作すると、許可証が壊れてしまいます。
  • 解決策:許可証が入らない、**「純粋な 64 ビットの数字」**を使うように変更しました。

⑤ 「封印された鍵」をいじくるな

  • 状況:関数の戻りアドレスなど、重要な鍵は「封印(Sealing)」されており、改変できないようになっています。Ruby は、この鍵の「住所部分」だけを変えて計算していました。
  • 問題:CHERI では、封印された鍵をいじると**「封印破壊エラー」**が起きます。
  • 解決策:計算する前に、いったん「純粋な数字」に変換して計算し、結果を整数として使うようにしました。

⑥ 「型」を間違えて変換するな

  • 状況:オブジェクトの構造を操作する際、size_t(サイズを表す型)を使ってアドレス計算をしていました。
  • 問題:CHERI では、size_t は「鍵」ではありません。鍵を size_t に変換して計算すると、「本物証明」が失われ、戻ってきた鍵は使えなくなります。
  • 解決策:計算には必ず**「鍵(ポインター)を扱える型」**を使うように統一しました。

3. 結果:新しい家は快適か?

これらの対策を施して Ruby を CHERI 上で動かした結果、以下のことがわかりました。

  • 性能:ほぼ元の Ruby と同じ速度(98% 程度)で動作しました。一部の特殊な処理(ファイバーという機能)では、最適化されたアセンブリコードが使えなくなったため少し遅くなりましたが、全体としては非常にスムーズです。
  • 安全性:CHERI の「万能鍵」システムのおかげで、メモリに関する脆弱性が物理的に防げるようになりました。
  • 教訓:「C 言語の裏技(未定義動作)」に頼っていた古いコードは、新しい安全な環境では通用しません。しかし、適切な対策をすれば、「安全」と「高速」を両立させることができます。

まとめ

この論文は、**「新しい安全な技術(CHERI)を導入する際、古いコードの『裏技』や『常識』が大きな壁になる」**ことを教えてくれます。

まるで、**「古い木造家屋を、最新の防犯マンションに移す際、単に鍵を交換するだけでなく、家の構造そのものを新しいルールに合わせて設計し直す必要がある」**ようなものです。著者たちは、Ruby という複雑なシステムを移住させることで、その「設計図の修正方法」を詳しく示してくれました。これにより、将来、他のプログラミング言語やシステムも、より安全な CHERI 環境へスムーズに移行できるようになります。