はじめに
こちらは Voicy Advent Calendar 2021 10日目の記事です。
Rustは近年、Stack Overflow Developer Surveyで「最も愛されているプログラミング言語」らしいです。
リソース管理に所有権という独特の機能があったり、マルチパラダイムで機能も豊富なので学習難易度は高いですが、C++に似た構文でかけ、C言語と同等速度で実行でき、かつメモリ安全性が保証されいます。
C++のメモリの管理は色々気にしないといけないことが多いので、早くてメモリ安全というとC/C++に起き変わりそうな予感がして、俄然習得意欲が沸いてきます。
C/C++が長らく独占している領域といえば、とりあえず浮かぶのはOSですが、今回は、RustとOSの状況について少し調べたことを紹介します。
Rust OSは結構ある
githubやgoogleで軽く調べた限りでも、いくつかRustで書かれたOSがありました。
- Redox 2015~
- Tock 2017~
- Theseus 2020~
- RedLeaf 2020~
arm向けや、マイクロカーネルなど、組込み向けのOSが多いように見受けられましたが、x86_64やi386向けもあるようです。 Githubでいくつかレポジトリを読んだうち、Theseus OSでState Spillという見知らぬ単語を知ったので紹介します。
State Spillとは?
初めて聞いた言葉だったので調べてみると下記の論文がヒットしました。 A Characterization of State Spill in Modern Operating Systems: 最新のオペレーティングシステムにおける状態流出の特性
近年のシステムソフトウェアでは、コンポーネント間でのインタラクションの際に、コンポーネント内の状態が通信先にのコンポーネントに漏れ出し、永続的に残ってしまう、という状況がしばしば起こっているようです。
それをState Spillと呼び、例えばAndroidのSystem serviceでState Spillが起きると、そのSystem Serviceがクラッシュした時に、それを使っていないアプリも一緒にクラッシュする、といったことが起きる原因になっているそう。
論文によると、Androidはコンポーネントの94%はState Spillが起きており、特にServiceやDispatcher周りで顕著とのことで、具体的には以下のような例が挙げられていました。
- ClipboardServiceでは、コピー/ペースト機能が停止する
- AlermManagerServiceでは、アラームが停止する、またそれによってタイムアウトによる自動ログアウトができなくなる
- AppWidgetServiceではアプリケーション・ウィジェットとの受信が解除できなくなる
- TextServiceManagerでは、文字入力時に予測変換不可になる、アプリケーション側が serviceの障害を検知できなくなる
クラッシュしてクリップボードが使えなくなる、というとsamsungのコピーを20回繰り返すとクラッシュする不具合を思いだしてしまうような話ですが、銀行アプリなどでの自動ログアウト機能もAlermManagerServiceで実装されていたりすることも多いそうで、State Spillが起因でセキュリティに重大な影響する障害も発生するそうです。論文によるとState Spilが起因によるOSの障害はいくらOSのモジュール化を押し進めても、設計自体を大きく変えなければ解決されない、ということです。
ちなみに、Androidに関して結構取り上げられていて、AndroidのState Spillに関して
- リソースをreadonlyにする
- メモリの内容をディスクに書きこむ
- アプリケーションの対象のエンティティのアドレス空間外に状態を移動させる
- サーバーから変更可能、かつ、クライアントからはreadonlyなメモリ空間をサーバーに提供する
など、改善のためのアプローチがいくつか提案されていました。
Theseus OS
https://github.com/theseus-os/Theseus
改めて、Theseusの紹介ですが、Rust製のOSで、OSとコンポーネントの間で、上記したState Spilltをいかに少なくするかに焦点を当てて設計されいます。
従来、OSにおいて、
- パフォーマンス
- ハードウェア分離(保護)
- 効率(低オーバヘッド)
と言ったOSが満たすべき性能は全てハードウェアが担っていましたが、これら全てをハードウェアのみで完全に実現することは不可能だという考えのもと、タスクとコンポーネント間の保護と分離を強化するために、ハードウェアはパフォーマンスと効率(低オーバヘッド)を、ソフトウェアはハードウェア保護を担当するように責務を分割させるのが基本的なアイディアということです。
それを実現するためににRust言語とコンパイラによる型安全性とメモリ安全性の保証に依存するようにしており、こうすることで、ハードウェアでの保護が不要になり、CPUモードの切り替えに起因するオーバーヘッドも減らせるため、パフォーマンスも向上するとのことです。
低レイヤーでunsafeを使うことになるのは避けられないですが、Rustはメモリ安全なので、既存のOSより大幅にメモリの安全性は確保され、またコンパイラの静的チェックを最大限利用する事でランタイムでのクラッシュを避けることも意図しているそうです。
コンパイラの恩恵を最大限受けるために、アプリケーション、システムサービス、コアカーネルコンポーネントを含む全てが、単一のカーネル空間と、単一の特権レベルで実行されます。リングプロテクション的には、Theseus OSは常にRing0で動作するということのようです。
コンポーネントに関しても、Theseusの構造は純粋にソフトウェアで定義されているので、セルのモジュール性の概念に基づいているとのことで、複数のセルが組み合わさったものがモジュールなので、既存のOSよりも細かな単位でコンポーネント化すると共に、セルを組み合わせてコンポーネントの拡張もできるようです。
終わりに
RustのOSへの採用の状況に関しては、直近では、RustがLinuxカーネルの第二言語に認定されたり、GoogleやMSでRustが一部採用されたりと、進捗は順調そうです。
Theseus以外にも色々な設計のRust OSのプロジェクトが進行してるようですが、Rustを用いることによって従来言語では難しかった設計でOSが構築できる可能性が見えてきたというところで、まだまだ先はわかりませんが、もしかしたら大きなパラダイムになるかもしれませんね。
他のRustのOSの関しては、全てではありませんが、こちらなど比較もいくつかあるようです。
また、自作OS本というのは定期的に出版されていて、有名なところでは、30日でできる! OS自作入門や、作って理解するOS x86系コンピュータを動かす理論と実装などもありますが、そこに最近Rust本が追加されました。
今回紹介したTheseus OSや他のOSで遊ぶのも面白いかもしれませんが、こちらも一度手にとって、年末休みに試してみるのも面白そうです。
次回は@entaku0818さんです!お楽しみに!