この記事では、SELinux ポリシーの構築方法について説明します。 SELinux ポリシーは、コア AOSP ポリシー (プラットフォーム) とデバイス固有のポリシー (ベンダー) の組み合わせから構築されます。 Android 4.4 から Android 7.0 までの SELinux ポリシー ビルド フローでは、すべての sepolicy フラグメントがマージされ、ルート ディレクトリにモノリシック ファイルが生成されました。これは、SoC ベンダーと ODM メーカーが、ポリシーが変更されるたびにboot.img
(非 A/B デバイスの場合) またはsystem.img
(A/B デバイスの場合) を変更することを意味しました。
Android 8.0 以降では、プラットフォームとベンダーのポリシーは個別に構築されます。 SOC と OEM は、ポリシーの一部を更新し、イメージ ( vendor.img
やboot.img
など) を構築し、プラットフォームの更新とは関係なくそれらのイメージを更新できます。
ただし、モジュール化された SELinux ポリシー ファイルは/vendor
パーティションに保存されるため、 init
プロセスはシステム パーティションとベンダー パーティションを事前にマウントして、これらのパーティションから SELinux ファイルを読み取り、システム ディレクトリ内のコア SELinux ファイルとマージできるようにする必要があります (ファイルをロードする前に)。カーネル)。
ソースファイル
SELinux を構築するためのロジックは次のファイルにあります。
-
external/selinux
: 外部 SELinux プロジェクト。SELinux ポリシーとラベルをコンパイルするための HOST コマンド ライン ユーティリティを構築するために使用されます。-
external/selinux/libselinux
: Android は、Android 固有のカスタマイズとともに、外部libselinux
プロジェクトのサブセットのみを使用します。詳細については、external/selinux/README.android
を参照してください。 -
external/selinux/libsepol
: -
external/selinux/checkpolicy
: SELinux ポリシー コンパイラ (ホスト実行可能ファイル:checkpolicy
、checkmodule
、およびdispol
)。libsepol
に依存します。
-
-
system/sepolicy
: コンテキストやポリシー ファイルを含む、コア Android SELinux ポリシー設定。主要な sepolicy ビルド ロジックもここにあります (system/sepolicy/Android.mk
)。
system/sepolicy
のファイルの詳細については、 「SELinux の実装」を参照してください。
Android 7.0以前
このセクションでは、Android 7.x 以前で SELinux ポリシーがどのように構築されるかについて説明します。
SELinux ポリシーの構築
SELinux ポリシーは、コア AOSP ポリシーとデバイス固有のカスタマイズを組み合わせて作成されます。結合されたポリシーは、ポリシー コンパイラとさまざまなチェッカーに渡されます。デバイス固有のカスタマイズは、デバイス固有のBoardconfig.mk
ファイルで定義されているBOARD_SEPOLICY_DIRS
変数を通じて行われます。このグローバル ビルド変数には、追加のポリシー ファイルを検索する順序を指定するディレクトリのリストが含まれています。
たとえば、SoC ベンダーと ODM はそれぞれ、SoC 固有の設定用に 1 つとデバイス固有の設定用にディレクトリを追加して、特定のデバイスの最終的な SELinux 構成を生成する場合があります。
-
BOARD_SEPOLICY_DIRS += device/ SOC /common/sepolicy
-
BOARD_SEPOLICY_DIRS += device/ SoC / DEVICE /sepolicy
system/sepolicy
内の file_contexts ファイルの内容とBOARD_SEPOLICY_DIRS
が連結されて、デバイス上にfile_contexts.bin
が生成されます。
sepolicy
ファイルは複数のソース ファイルで構成されます。
- プレーンテキストの
policy.conf
security_classes
、initial_sids
、*.te
ファイル、genfs_contexts
、およびport_contexts
をこの順序で連結することによって生成されます。 - 各ファイル (
security_classes
など) の内容は、system/sepolicy/
およびBOARDS_SEPOLICY_DIRS
の下にある同じ名前のファイルを連結したものです。 -
policy.conf
構文チェックのために SELinux コンパイラに送信され、デバイス上でsepolicy
としてバイナリ形式にコンパイルされます。
SELinux ファイル
コンパイル後、7.x 以前を実行している Android デバイスには通常、次の SELinux 関連ファイルが含まれます。
-
selinux_version
- sepolicy: ポリシー ファイル (
security_classes
、initial_sids
、*.te
など) を結合した後のバイナリ出力 file_contexts
-
property_contexts
-
seapp_contexts
-
service_contexts
-
system/etc/mac_permissions.xml
詳細については、 「SELinux の実装」を参照してください。
SELinuxの初期化
システムの起動時、SELinux は許容モードになります (強制モードではありません)。 init プロセスは次のタスクを実行します。
-
/sys/fs/selinux/load
を介してsepolicy
ファイルを ramdisk からカーネルにロードします。 - SELinux を強制モードに切り替えます。
-
re-exec()
を実行して、SELinux ドメイン ルールをそれ自体に適用します。
起動時間を短縮するには、できるだけ早くinit
プロセスでre-exec()
を実行します。
Android 8.0以降
Android 8.0 では、SELinux ポリシーがプラットフォーム コンポーネントとベンダー コンポーネントに分割され、互換性を維持しながらプラットフォーム/ベンダー ポリシーを独立して更新できるようになりました。
プラットフォーム sepolicy は、特定のタイプと属性をベンダー ポリシー作成者にエクスポートするために、プラットフォーム プライベート部分とプラットフォーム パブリック部分にさらに分割されます。プラットフォームのパブリック型/属性は、特定のプラットフォーム バージョンの安定した API として維持されることが保証されています。以前のプラットフォームのパブリック型/属性との互換性は、プラットフォーム マッピング ファイルを使用していくつかのバージョンで保証できます。
プラットフォームの公開ポリシー
プラットフォームの public sepolicy にはsystem/sepolicy/public
で定義されているすべてのものが含まれます。プラットフォームは、パブリック ポリシーに基づいて定義された型と属性が、特定のプラットフォーム バージョンの安定した API であると想定できます。これは、ベンダー (つまり、デバイス) ポリシー開発者が追加のデバイス固有のポリシーを作成できるプラットフォームによってエクスポートされる sepolicy の一部を形成します。
タイプは、 PLATFORM_SEPOLICY_VERSION
ビルド変数で定義された、ベンダー ファイルが書き込まれるポリシーのバージョンに従ってバージョン管理されます。バージョン管理されたパブリック ポリシーは、ベンダー ポリシーに組み込まれ、(元の形式で) プラットフォーム ポリシーに組み込まれます。したがって、最終ポリシーには、プライベート プラットフォーム ポリシー、現在のプラットフォームのパブリック ポリシー、デバイス固有のポリシー、およびデバイス ポリシーが作成されたプラットフォーム バージョンに対応するバージョン管理されたパブリック ポリシーが含まれます。
プラットフォームのプライベートセポリシー
プラットフォームのプライベート sepolicy /system/sepolicy/private
で定義されたすべてが含まれます。ポリシーのこの部分は、プラットフォーム機能に必要なプラットフォームのみのタイプ、権限、属性を形成します。これらは、 vendor/device
ポリシー作成者にはエクスポートされません。非プラットフォーム ポリシー作成者は、プラットフォーム プライベート sepolicy で定義されたタイプ/属性/ルールに基づいてポリシー拡張を作成してはなりません。さらに、これらのルールは変更が許可されているか、フレームワークのみの更新の一部として削除される可能性があります。
プラットフォームのプライベートマッピング
プラットフォーム プライベート マッピングには、以前のプラットフォーム バージョンのプラットフォーム パブリック ポリシーで公開されている属性を、現在のプラットフォーム パブリック ポリシーで使用されている具体的なタイプにマップするポリシー ステートメントが含まれています。これにより、以前のプラットフォーム パブリック sepolicy バージョンのプラットフォーム パブリック属性に基づいて作成されたベンダー ポリシーが引き続き機能することが保証されます。バージョン管理は、特定のプラットフォーム バージョンの AOSP で設定されたPLATFORM_SEPOLICY_VERSION
ビルド変数に基づいています。このプラットフォームがベンダー ポリシーを受け入れることが期待される以前のプラットフォーム バージョンごとに個別のマッピング ファイルが存在します。詳細については、 「互換性」を参照してください。
Android 11以降
system_ext と製品の sepolicy
Android 11では、system_extポリシーとproductポリシーが追加されました。プラットフォーム se ポリシーと同様に、system_ext ポリシーと製品ポリシーは、パブリック ポリシーとプライベート ポリシーに分割されます。
公共ポリシーはベンダーにエクスポートされます。型と属性が安定した API になり、ベンダー ポリシーがパブリック ポリシーの型と属性を参照できるようになります。タイプはPLATFORM_SEPOLICY_VERSION
に従ってバージョン管理され、バージョン管理されたポリシーはベンダー ポリシーに含まれます。 system_ext と product パーティションのそれぞれに独自のポリシーが含まれます。
プライベート ポリシーには、system_ext および product パーティションの機能に必要な system_ext のみおよび product のみのタイプ、アクセス許可、および属性が含まれています。プライベート ポリシーはベンダーには見えず、これらのルールは内部的なものであり、変更が許可されていることを意味します。
system_ext と製品のマッピング
system_ext と product は、指定されたパブリック型をベンダーにエクスポートできます。ただし、互換性を維持する責任は各パートナーにあります。互換性を確保するために、パートナーは、以前のバージョンのバージョン属性を現在のパブリック sepolicy で使用されている具体的なタイプにマップする独自のマッピング ファイルを提供できます。
- system_ext のマッピング ファイルをインストールするには、必要なマッピング情報を含む cil ファイルを
{SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil
に配置し、system_ext_{ver}.cil
をPRODUCT_PACKAGES
に追加します。 - 製品のマッピング ファイルをインストールするには、必要なマッピング情報を含む cil ファイルを
{PRODUCT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil
に配置し、product_{ver}.cil
をPRODUCT_PACKAGES
に追加します。 redbullデバイスのプロダクトパーティションのマッピングファイルを追加する例を参照してください。 - ポリシーを SELinux 共通中間言語 (CIL) 形式に変換します。具体的には次のとおりです。
- パブリック プラットフォーム ポリシー (システム + システム拡張 + 製品)
- プライベート + パブリック ポリシーの組み合わせ
- パブリック + ベンダーおよび
BOARD_SEPOLICY_DIRS
ポリシー
- ベンダー ポリシーの一部としてパブリックによって提供されるポリシーのバージョン管理。これは、生成されたパブリック CIL ポリシーを使用して、どの部分をプラットフォーム ポリシーにリンクする属性に変換する必要があるかを、パブリック + ベンダー +
BOARD_SEPOLICY_DIRS
の組み合わせポリシーに通知することによって行われます。 - プラットフォームとベンダー部分をリンクするマッピング ファイルを作成します。最初は、これはパブリック ポリシーのタイプをベンダー ポリシーの対応する属性にリンクするだけです。その後、将来のプラットフォーム バージョンで維持されるファイルの基礎も提供され、このプラットフォーム バージョンを対象とするベンダー ポリシーとの互換性が可能になります。
- ポリシー ファイルを結合する (デバイス上のソリューションとプリコンパイルされたソリューションの両方について説明します)。
- マッピング、プラットフォーム、ベンダー ポリシーを組み合わせます。
- 出力されたバイナリ ポリシー ファイルをコンパイルします。
-
/system/etc/selinux/plat_sepolicy_and_mapping.sha256
と/{partition}/etc/selinux/precompiled_sepolicy.plat_sepolicy_and_mapping.sha256
は両方とも存在し、同一です。 -
/system_ext/etc/selinux/system_ext_sepolicy_and_mapping.sha256
と/{partition}/etc/selinux/precompiled_sepolicy.system_ext_sepolicy_and_mapping.sha256
の両方が存在しません。あるいは両方が存在し、同一です。 -
/product/etc/selinux/product_sepolicy_and_mapping.sha256
と/{partition}/etc/selinux/precompiled_sepolicy.product_sepolicy_and_mapping.sha256
の両方が存在しません。あるいは両方が存在し、同一です。
SELinux ポリシーの構築
Android 8.0 の SELinux ポリシーは、 /system
と/vendor
の部分を組み合わせて作成されます。これを適切に設定するためのロジックは/platform/system/sepolicy/Android.mk
にあります。
ポリシーは次の場所に存在します。
位置 | 含まれています |
---|---|
system/sepolicy/public | プラットフォームの sepolicy API |
system/sepolicy/private | プラットフォーム実装の詳細 (ベンダーは無視できます) |
system/sepolicy/vendor | ベンダーが使用できるポリシーおよびコンテキスト ファイル (ベンダーは必要に応じて無視できます) |
BOARD_SEPOLICY_DIRS | ベンダーのセキュリティポリシー |
BOARD_ODM_SEPOLICY_DIRS (Android 9 以降) | ODM セポリシー |
SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS (Android 11 以降) | System_ext の sepolicy API |
SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS (Android 11 以降) | System_ext 実装の詳細 (ベンダーは無視できます) |
PRODUCT_PUBLIC_SEPOLICY_DIRS (Android 11 以降) | 製品の sepolicy API |
PRODUCT_PRIVATE_SEPOLICY_DIRS (Android 11 以降) | 製品実装の詳細 (ベンダーは無視できます) |
ビルド システムはこのポリシーを採用し、対応するパーティション上に system、system_ext、product、vendor、および odm ポリシー コンポーネントを生成します。手順には次のものが含まれます。
プリコンパイルされた SELinux ポリシー
init
が SELinux を有効にする前に、 init
パーティション ( system
、 system_ext
、 product
、 vendor
およびodm
) からすべての CIL ファイルを収集し、それらをカーネルにロードできる形式のバイナリ ポリシーにコンパイルします。コンパイルには時間がかかるため (通常は 1 ~ 2 秒)、CIL ファイルはビルド時にプリコンパイルされ、sha256 ハッシュとともに/vendor/etc/selinux/precompiled_sepolicy
または/odm/etc/selinux/precompiled_sepolicy
に配置されます。入力 CIL ファイルの数。実行時に、 init
ハッシュを比較してポリシー ファイルが更新されたかどうかを確認します。何も変更されていない場合、 init
プリコンパイルされたポリシーをロードします。そうでない場合、 init
オンザフライでコンパイルし、プリコンパイルされたものの代わりにそれを使用します。
具体的には、次の条件がすべて満たされる場合に、プリコンパイルされたポリシーが使用されます。ここで、 {partition}
、プリコンパイルされたポリシーが存在するパーティション ( vendor
またはodm
のいずれか) を表します。
それらのいずれかが異なる場合、 init
デバイス上のコンパイル パスにフォールバックします。詳細についてはsystem/core/init/selinux.cpp
を参照してください。