本記事では、Firefox OS のシステムセキュリティモデルの概要を説明します。すなわち、オペレーティングシステムがどのようにセキュリティや許可設定の適用を提供するかを説明します。
用語
システムセキュリティモデルに踏み込む前に、ここで理解しておきたいキーワードを挙げます。
- Web アプリケーション
- Web アプリケーション、open web app、moz app、あるいはアプリケーションとは、HTML、JavaScript などのオープンな Web 技術で記述され、Firefox OS (または、同様のインストール可能なアプリモデルをサポートする、他のプラットフォーム) で動作するプログラムです。B2G でユーザが目にするアプリケーションはすべて、Web アプリケーションです。例えば、ダイヤラーは Firefox OS の Web app です。ここでは、ブラウザ内で動作しているページは Web app とは呼びません。
- b2g プロセス
- Firefox OS の b2g プロセスは、一般的に "b2g" または "Gecko" と呼ばれます。これは本質的には、高い権限で実行 (すなわち root として実行) しているアプリケーションであり、任意のアプリケーションが持つすべてのリソースやデバイスへのアクセスを制御します。
- Content プロセス
- これは b2g プロセスから生み出された子プロセスで、b2g プロセスと通信します。このプロセスは、Web アプリケーションを表します。またこれは、低い権限のプロセス (すなわち通常のユーザで実行され、オペレーティングシステムへのアクセスや参照範囲はごく限られています) です。Content プロセスは、プロセス間通信 (IPC) を使用して Firefox OS のコアプロセスと通信します。
- IPDL
- Intercommunication Protocol Definition Language のことであり、詳しくは IPDL をご覧ください。
- AOSP
- Android Open Source Project のことです。
- システムコール
- ユーザ空間 (プロセス) とカーネルとの間で対話するためのインターフェイスです。この他に、ユーザ空間とカーネルが直接対話する方法はありません。
- DAC、MAC
- 任意アクセス制御 (Discretionary Access Control) (ユーザが設定する) および強制アクセス制御 (Mandatory Access Control) (カーネルにより強制される) のことです。
- FOTA
- ファームウェアの Over The Air (Firmware Over The Air) 更新システムの仕組みです。ファームウェア全体の更新を意味する用語であり、通常は "over the air"、すなわち無線通信を用いて携帯電話へ送信します。
- MSU、MAR
- Mozilla System Updater および Mozilla ARchive のことです。Gecko の更新を意味する用語であり、デスクトップ版 Firefox と同じ更新機構およびアーカイブ形式を使用します。
Firefox OS システムセキュリティモデルの目的と範囲
Firefox OS システムセキュリティモデルは、以下のように設計しています:
- Web アプリケーションがアクセスまたは使用できるリソースの範囲を、制限および強制します。
- いくつかのセキュリティ層が、オペレーティングシステムで正しく使用されるようにします。
- Gonk 層から、セキュリティバグによって引き起こされる脆弱性の影響を制限および抑制します。
- Web アプリケーションの許可設定やセキュリティ機能に関するアプリケーションについては、アプリケーションセキュリティモデルで詳しく説明します。
それぞれの目的の詳細説明や Firefox OS でこれらをどのように対処しているかについては、以降の章で説明します。
許可設定の適用
アプリケーションセキュリティモデルでは、どのようにしてユーザが直接または信頼されたサードパーティを通してアプリケーションの許可設定を承諾するかを説明しています。これらの許可設定はコアプロセス への IPC コールによって実現する、リソースへの全アクセスに強制することにより、content プロセス に適用されます。
- Firefox OS のコアプロセスである
b2g
は高い権限を持ち、ほとんどのハードウェアデバイスにアクセスできます。 - Web アプリケーションは低い権限の content プロセスで動作して、また IPC を使用して
b2g
コアプロセスとの通信のみが可能であり、IPC は IPDL で実装されます。 - content プロセスは、リソースにオペレーティングシステムレベルではアクセスできません。
- それぞれの Web API は 1 つ以上の IPDL プロトコル定義ファイル (*.ipdl) が結びつけられます。
- Firefox OS の content プロセスは IPDL の仕組みを通してのみコアプロセスと通信でき、その仕組みは content のためにアクションを行います。
Content プロセスの初期化
すべての Web アプリケーションは低い権限および分離されたプロセスで実行します: それは Firefox OS の content プロセス です。このプロセスは、特別な <iframe>
のタイプである <iframe mozapp> に達したときに、b2g
コアプロセスによって起動されます。これは Web アプリケーションと残りの content とを分離するとともに、マニフェストに強く結びつけられています (詳しくはアプリケーションセキュリティモデルをご覧ください)。content プロセスは、"out of process" コンテナまたは OOP と呼ばれるコンテナ内で開始します。これは plugin-container
プロセスに相当しており、デスクトップ版 Firefox の plugin-container
で使用しているものと似たコードを使用しています。
リスク
- Web アプリケーションの content プロセスを生み出す際の情報漏えい。
- オペレーティングシステムのりソースへのアクセス、および
b2g
と同じ水準への権限昇格。 - content プロセス初期化の迂回。
実装
b2g プロセスでの初期化
以下の順序で行います:
fork()
setuid(new, different, unused user id|nobody)
(特権がないユーザ)chrdir('/')
execve('plugin-container')
これは、OOP プロセスが分離されたメモリ空間 (新しいプロセス)、および b2g
と同じ水準の権限に昇格できない低権限のユーザで実行するようにします。
ファイルディスクリプタの制御
ファイルディスクリプタは、ホワイトリスト方式を使用して制御します。許可されたファイルディスクリプタ (FD) のリストは、mFileMap
オブジェクト内に生成および保管されます。LaunchApp()
関数は、ホワイトリスト上にないすべての FD を強制的に閉じます。これは、fork()
(FD がコピーされるとき) と execve()
(新しいアプリが実行開始するとき) の間に行います。
ブラックリスト (close-on-exec フラグ: CLOEXEC
) を使用する伝統的な方式とは異なり、開いたままの FD がないようにします。従って、より信頼できます。
Content プロセスのサンドボックス化 (低権限の content プロセス)
リスク
- 任意のコード実行につながる、Gecko ランタイムのメモリ破壊や論理エラー。
- 同様に任意のコード実行につながる、オペレーティングシステム自体 (特にカーネル) の欠陥。
- 情報漏えい、ファイルシステムへの読み書きアクセス。
以下は前述のリスクの簡単な要約に加えて、サンドボックス有効時の脅威をモデル化した表です。
ねらい: 攻撃者が content プロセスで任意のコードを実行した場合に発生する脅威を以下に示します。言い換えると、攻撃者はすでに Gecko の脆弱性を発見しています。
脅威 | 考えられる影響 | 要因となる可能性 | 提案された緩和策 |
---|---|---|---|
悪意のある content プロセスが、既存のカーネル脆弱性を悪用する "2 段階の攻撃" |
重大: デバイスの完全な制御 | 低: content プロセスが可能なシステムコールの数は制限されている。 |
|
親プロセスへの権限昇格 悪意のある content プロセスが、IPDL を通して親プロセスを悪用する "2 段階の攻撃" |
高: かなりの量の重要なシステムコールを実行される可能性 (データ喪失、カメラへのアクセス、ネットワークアクセスなど) | 中: 親プロセスには大量のコードがある。攻撃箇所が多数存在する。最小限のサニタイズを施したデータが IPDL で送信される (例えば、ポインタの送信が可能)。 |
|
悪意のある content プロセスによる、既存のカーネル脆弱性を悪用した親プロセスの侵害 "3 段階の攻撃". |
重大: デバイスの完全な制御 |
低: 親プロセスに、IPDL を通したアクセスが可能なバグが必要。 親プロセスがアクセスできるシステムコール内に、カーネルの脆弱性が必要 (content プロセスに比べて、親プロセスはより多くのシステムコールにアクセス可能)。 |
|
悪意のある content プロセス、親プロセス、あるいは Web アプリケーションが、デバイスのハードウェアに存在するバグを悪用する "1 および 2 段階の攻撃" |
高: 高い権限の操作 (電話の発信、SMS の送信など) を行われる可能性 重大: ハードウェアレベルでコードを実行し、デバイスを完全に制御する可能性 |
低: ハードウェアとの通信経路、IPDL またはシステムコールを通した許可、およびハードウェアのバグが必要。 |
|
注記: PaX (Protection Against eXecution) は GrSecurity (docs) によるカーネルパッチで、"PaX" に加えて UDEREF や SMAP といった付加的な保護機能も実装しています。
リストアップしていない脆弱性は、サンドボックス自体で緩和します。
実装
スーパーバイザーは未実装です。
注記: Content プロセスは Web アプリケーションを実行しており、サンドボックス化されたプロセスです。
Gecko の API 実装
content プロセス内で JavaScript を経由して公開される API は、ファイルシステムのリソースに直接アクセスしてはいけません。代わりに、それらはリソースへの IPDL コールを発行します。つまり、リソースにアクセスする API は、content プロセスに代わってリソースにアクセスするためのコンポーネントを親プロセスに持っていなければなりません。
コールを実装する際は、追加の策をとらなければなりません。すべての入力情報は、親プロセスによってサニタイズされます。content プロセスは信頼できず、また content プロセスから来る IPDL メッセージも信頼できません。
警告: content プロセスに与えられる信頼はサンドボックスの回避に使用でき、また使用されるでしょう。
seccomp とは何か
seccomp とは、セキュアコンピューティングモード (secure computing mode)を意味します。現在は 2 つのバージョンの seccomp があります:
-
seccomp
: Linux カーネル 2.6.12 以上で使用可能-
seccomp
を有効にすると、プロセスのread
、write
、sigreturn
、exit
を行うためのシステムコールを制限します。 -
prctl()
システムコールを使用します。 -
プロセスの初期化を始めた後、調停領域で開始可能です。
-
-
seccomp-bpf
: seccomp mode filter または mode 2 とも呼ばれ、Linux カーネル 3.5 以上で利用可能-
seccomp
と同じですが、システムコールのフィルタに BPF を実装しています。 -
ハードコードされたシステムコールの代わりに、初期化時にシステムコールや引数のホワイトリストを使用可能です。
-
より柔軟性があり、"より自由なサンドボックス" を実現できます。やや弱いサンドボックス向け、および "より厳しいサンドボックス" へのスムーズな移行パス向けに有用です。
-
特権を復帰するためのプロセスや子プロセスを妨げるフラグを追加します。
-
注記: 柔軟性を理由に私たちは seccomp-bpf の使用を決めて、それゆえに seccomp-bfd を 3.5 未満のカーネルにバックポートしました。これには、ほとんどの現行 Android カーネルも含みます。パッチはすでに使用できる状態であり、通常は競合なしに適用できます (バグ 790923 をご覧ください)。
Seccomp-bpf のパフォーマンス
seccomp-bpf
はシステムコールがあるたびに、パフォーマンスに影響を与えます。実装に依存して測定するような、正確なベンチマークはありません。
実行中のプロセス向けに seccomp-bdf が有効でシステムコールが行われるときに、最大 1% 程度パフォーマンスに影響を与えると推定しています。これは QA で測定すべきです。
私たちのプロセスモデルではシステムコールの数を著しく削減したため、実際のパフォーマンスへの影響はほぼないであろうと予測しています。
しかし IPDL コールはその実装により、レイテンシを追加してパフォーマンスを下げるでしょう。OpenGL コールのようなリソース集約的 API 向けの Chromium の実装を見ることを強く推奨します。seccomp-bpf
と同様に、IPDL コールの数を最小化すればパフォーマンスへの影響は最小化されるでしょう。
実装
Gecko では --enable-content-sandbox
で seccomp
を有効化します。
拒否されたシステムコールがある場合に報告するレポーターはデフォルトでビルドされません。--enable-content-sandbox-reporter
で有効化します。
コードの大部分は gecko/security/sandbox
にあります。ホワイトリスト自体は gecko/security/sandbox/seccomp_filter.h
にあります。
ホワイトリストには、区画化に使用できるシステムコールが含まれます。通常、これらのシステムコールには理由を表すコメントがあり、最終的に影響があるコードが修正されたときに削除されるでしょう。従って、サンドボックスを破壊してあまり深く考慮せずにホワイトリスト内のシステムコールを追加するコードを加えることはほとんどありません。疑わしいものはバグを提示します。しかしこれはほとんどの場合に不正確であり、代わりにリソースは制御されて b2g プロセスにアクセスされ、アクセスが承諾されるかデータがサニタイズされた場合に content プロセスへ渡されます。
ファイルシステムの堅固化
リスク
- 他のユーザに属するファイルの書き込み、削除、読み取り。これは情報漏えいや権限昇格といった予期せぬ動作につながるおそれがあります。
- アプリケーションの脆弱性を通した、ネイティブコードの実行。
setuid
プログラムの脆弱性 (そして権限昇格)。
実装
理論的根拠は、ユーザのコンテンツを含む領域のみ読み書き可能としてよく (将来 OS 自身が新たに読み書き可能な領域を要求しない限り)、また nodev
、nosuid
、および noexec
オプションを含まなければならない、ということです。標準的なファイルシステムのマウントは、以下のように制限します:
マウントポイント | ファイルシステム | オプション |
---|---|---|
/ |
rootfs | 読み取り専用 |
/dev |
tmpfs | 読み書き可能、nosuid、noexec、mode=0755 |
/dev/pts |
ptsfs | 読み書き可能、nosuid、noexec、mode=0600 |
/proc |
proc | 読み書き可能、nosuid、nodev、noexec |
/sys |
sysfs | 読み書き可能、nosuid、nodev、noexec |
/cache |
yaffs2 または ext4 | 読み書き可能、nosuid、nodev、noexec |
/efs |
yaffs2 または ext4 | 読み書き可能、nosuid、nodev、noexec |
/system |
ext4 | 読み取り専用、nodev |
/data |
ext4 | 読み書き可能、nosuid、nodev、noexec |
/mnt/sdcard |
ext4 または vfat | 読み書き可能、nosuid、nodev、noexec、uid=1000、fmask=0702、dmask=0702 |
/acct |
cgroup | 読み書き可能、nosuid、nodev、noexec |
/dev/cpuctl |
cgroup | 読み書き可能、nosuid、nodev、noexec |
注記: 正確なマウントポイントは変わるかもしれません。
Linux DAC
Linux DAC は、有名な Linux のファイルシステムパーミッションモデルを表します。
注記: これは伝統的な ユーザ/グループ/その他 のパーミッションモデルであり、Linux POSIX 1.e ACL ではありません。
- Web アプリケーションシステムのユーザは、どのファイルに対しても書き込みアクセスができません。
setuid
バイナリの使用は、必要に応じて制限されます。- 新たな content プロセスは、穏健な
umask
で開始します。
安全なシステム更新
リスク
- 汚染された更新パッケージデータにより、信頼されていない更新パッケージがインストールされる
- 妥協的な更新チェック:
- ユーザは新しい更新が使用できることに気づかない。
- ユーザが期限切れの更新パッケージを取得する。これはデバイス上のソフトウェアを事実上ダウングレードします。
- 更新のインストール中にシステムの状態が汚染されたり不明になったりする。これは (例えば) 以下のような状況を引き起こします:
- インストール中に見落とされる要素がある。それにはセキュリティの修正が含まれるかもしれません。
- アップグレード後に、汚染されたシステムによってセキュリティの修正が復活する。
- デバイスで実行している更新チェックの仕組みに存在する脆弱性。
- 既知の脆弱性を持つソフトウェアコンポーネントの更新または追跡の欠如。
実装
Firefox OS プラットフォームのアップグレードやパッチ適用は、携帯電話機内のシステムイメージの継続的な整合性を保証する、セキュアな Mozilla のプロセスを使用して展開されます。更新パッケージは、その組み立て、構築、テスト、デジタル署名の実施について責任を持つ、既知の信頼された提供元 (通常はデバイスの OEM) によって作成されます。
ファームウェアの over the air 更新
システム更新は、Firefox OS スタックの全体あるいは一部に関与する場合があります。更新内容に Gonk の変更が含まれている場合は、インストールプロセスとして FOTA (Firmware Over the Air) を使用します。FOTA アップデートには、デバイス管理 (FOTA、ファームウェア、ドライバ)、設定管理 (Firefox OS の設定)、セキュリティ更新、Gaia、Gecko、あるいは他のパッチといった、Firefox OS スタックの他の部分に対するものが含まれることもあります。
MSU/MAR 更新
Gonk に関与しないアップデートは、Mozilla System Update Utility を使用して実施できます。Firefox OS では、Firefox のデスクトップ製品と同じ更新フレームワーク、プロセス、Mozilla ARchive (MAR) 形式 (更新パッケージで使用) を使用します。
更新サービス
注記: 更新サービスは OEM から提供される場合があります。
携帯電話機内蔵の更新サービスが、定期的にシステム更新の確認を行います。更新パッケージが入手可能になって更新サービスにより検出されると、インストール実施の確認をユーザに促します。更新パッケージをモバイルデバイスへインストールする前に、デバイスのストレージで更新の適用に十分な領域があるかを確認します。またディストリビューションの検証が行われます:
- 更新の提供元 (システム更新やマニフェストの出所のプロトコル:ドメイン:ポートの検証)
- ファイルの整合性 (暗号技術によるハッシュの確認)
- コード署名 (信頼されたルートに対する証明書の確認)
更新プロセスの間に、以下のセキュリティ対策を使用します:
- Mozilla は更新を、信頼された証明書を使用する SSL 接続で取得することを推奨および期待します。
- ファームウェアパッケージをインストールする前に、強力な暗号による検証を要求します。
- 更新プロセスを始める前に、完全な更新を特定の安全な場所にダウンロードしなければなりません。
- システムは更新プロセスを始めるときに、Web アプリケーションを実行しない安全な状態でなければなりません。
- 鍵情報は、デバイス内の安全な場所に保管しなければなりません。
携帯電話機に更新が適切に適用されたことを保証するための、厳密なチェックがあります。
注記: プラットフォームの更新について、詳しくは Firefox OS の更新パッケージを作成、適用する をご覧ください。