Google は、黒人コミュニティに対する人種平等の促進に取り組んでいます。取り組みを見る

SELinux のコンセプト

SELinux のコンセプトについて知識を深めるには、このページをご覧ください。

強制アクセス制御

Security Enhanced Linux(SELinux)は、Linux オペレーティング システム用の強制アクセス制御(MAC)システムです。MAC システムは、Linux で一般的な任意アクセス制御(DAC)システムとは異なります。DAC システムにはオーナーシップのコンセプトがあり、それによって特定のリソースのオーナーが、そのリソースに関連するアクセス権限を制御します。DAC システムでは一般的に制御が緩いため、意図しない権限昇格が発生しやすくなります。一方 MAC システムでは、すべてのアクセス試行に関する決定を中核となる制御システムが行います。

SELinux は Linux セキュリティ モジュール(LSM)フレームワークの一部として実装されており、さまざまなカーネル オブジェクトと、それに対するセキュリティ上重要なアクションを認識します。これら各アクションが実行される時点で LSM フック機能が呼び出され、不透明なセキュリティ オブジェクトに保存されている情報に基づいて、アクションを許可するかどうかが判断されます。SELinux では、これらのフックの実装とセキュリティ オブジェクトの管理を行い、それらを独自のポリシーと組み合わせて、アクセスの決定を判断します。

Android のアクセス制御ポリシーは、Android の他のセキュリティ対策と組み合わせて使用することで、マシンやアカウントの侵害による損害の可能性を大幅に低下させます。Android の任意アクセス制御や強制アクセス制御などのツールを使用することで、ソフトウェアを確実に最小の権限レベルで実行するための構造が実現します。これによって、攻撃の影響が緩和され、データの上書きや送信を行う異常なプロセスが発生する可能性が低下します。

Android 4.3 以降では、従来の任意アクセス制御(DAC)環境に加えて、SELinux による強制アクセス制御(MAC)が導入されています。たとえば、raw ブロック デバイスに書き込むには、通常、ソフトウェアをルートユーザー アカウントとして実行する必要があります。従来型の DAC ベースの Linux 環境では、ルートユーザーが侵害されると、そのユーザーがすべての raw ブロック デバイスに書き込めるようになります。しかし SELinux を使用すると、こうしたデバイスにラベルを付けることで、ルート権限が割り当てられたプロセスが書き込めるデバイスを、関連するポリシーで指定されたデバイスに限定できます。これにより、そのプロセスが特定の raw ブロック デバイス以外のデータとシステム設定に上書きできなくなります。

その他の脅威の例と、SELinux を使用してそれらに対応する方法については、ユースケースをご覧ください。

適用レベル

SELinux はさまざまなモードで実装できます。

  • Permissive - SELinux セキュリティ ポリシーが適用されず、ログへの記録のみが行われます。
  • Enforcing - セキュリティ ポリシーが適用され、ログに記録されます。エラーは EPERM エラーとして示されます。

どちらか 1 つのモードを選択することで、ポリシーによって対処するか、潜在的なエラーを収集するだけにするかを決定できます。Permissive は特に実装時に役立ちます。

ラベル、ルール、ドメイン

SELinux は、アクションとポリシーの一致にラベルを使用します。ラベルにより、何が許可されるかが決定されます。SELinux では、ソケット、ファイル、プロセスそれぞれにラベルがあります。SELinux の決定は、これらのオブジェクトに割り当てられたラベルと、それらのインタラクションを定義するポリシーに基づきます。

SELinux では、ラベルは user:role:type:mls_level の形式を取ります。この形式で、タイプはアクセスの決定を行うためのメインのコンポーネントであり、この決定はラベルを構成するその他のセクションのコンポーネントによって変更される場合があります。オブジェクトはクラスにマッピングされ、各クラスに対するさまざまなタイプのアクセスは、権限によって表されます。

ポリシールールは allow domains types:classes permissions; の形式を取ります。各要素の説明は以下のとおりです。

  • Domain - プロセスまたはプロセスのセットのラベル。プロセスの 1 つのタイプであるため、ドメインタイプとも呼ばれます。
  • Type - オブジェクト(ファイル、ソケットなど)またはオブジェクトのセットのラベル。
  • Class - アクセス対象のオブジェクトの種類(ファイル、ソケットなど)。
  • Permission - 実行される操作(読み取り、書き込みなど)。

この形式の使用例は、次のような構造になります。

allow appdomain app_data_file:file rw_file_perms;

この例は、すべてのアプリケーション ドメインで、app_data_file とラベル付けされているファイルの読み取りと書き込みが許可されていることを示しています。このルールは、global_macros ファイルで定義されているマクロによって異なります。te_macros ファイルには、他にも便利なマクロが用意されています。マクロは、クラス、権限、ルールの一般的なグループ化のために用意されており、関連する権限の拒否によるエラーの可能性を低減させるために使用します。それらのマクロファイルは system/sepolicy ディレクトリにあります。Android 8.0 以降では、サポートされているその他のパブリック sepolicy と合わせて、public サブディレクトリにあります。

ルール内でドメインやタイプを別個に指定するだけでなく、属性を使用して、複数のドメインまたはタイプを参照することもできます。属性は、複数のドメインまたはタイプを表す名前です。それぞれのドメインまたはタイプは、任意の数の属性に関連付けることができます。属性名を指定するルールを記述すると、その属性に関連付けられているドメインまたはタイプのリストに、指定した名前が自動的に拡張されます。たとえば、domain 属性はすべてのプロセス ドメインに関連付けられており、file_type 属性はすべてのファイルタイプに関連付けられています。

上記の構文を使用して、SELinux ポリシーの基本となる avc ルールを作成します。ルールの形式は次のようになります。

RULE_VARIANT SOURCE_TYPES TARGET_TYPES : CLASSES PERMISSIONS

このルールは、いずれかの source_types でラベル付けされた対象が、いずれかの target_types ラベルを持つ classes クラスのオブジェクトに対して、いずれかの permissions に対応するアクションを行うときに、どのようなことが発生するかを規定しています。こうしたルールのうち最も一般的なのは、次のような許可ルールです。

allow domain null_device:chr_file { open };

このルールは、domain 属性に関連付けられている任意の domain が、許可 open で記述されているアクションを、null_devicetarget_type ラベルを持つクラス chr_file(キャラクター デバイス ファイル)のオブジェクトに対して行うことを許可しています。実際には、このルールは他の権限が追加されて使用されます。

allow domain null_device:chr_file { getattr open read ioctl lock append write};

domain がすべてのプロセス ドメインに割り当てられている属性であることと、null_device がキャラクター デバイス /dev/null のラベルであるであることを考えると、このルールは基本的に /dev/null への読み取りと書き込みを許可しています。

domain は一般的にプロセスに対応し、プロセスに関連するラベルを持ちます。

たとえば、一般的な Android アプリで独自のプロセスを実行するとき、そのプロセスには制限された特定の権限を付与する untrusted_app ラベルが付与されます。

システムに組み込まれたプラットフォーム アプリは、個別のラベルが付与されて動作し、一連の個別の権限が与えられます。コアの Android システムの一部であるシステム UID アプリは、system_app ラベルが付与されて動作し、プラットフォーム アプリとも異なる権限が与えられます。

ドメインに対し、次の汎用ラベルに直接アクセスすることを許可してはなりません。代わりに、1 つ以上のオブジェクトに対して具体的なタイプを作成して対処してください。

  • socket_device
  • device
  • block_device
  • default_service
  • system_data_file
  • tmpfs