SELinux ポリシーのビルド

この記事では、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.imgboot.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 :
      • chkcon : セキュリティ コンテキストが特定のバイナリ ポリシー (ホスト実行可能ファイル) に対して有効かどうかを判断します。
      • libsepol : バイナリ セキュリティ ポリシーを操作するための SELinux ライブラリ (ホスト静的/共有ライブラリ、ターゲット静的ライブラリ)。
    • external/selinux/checkpolicy : SELinux ポリシー コンパイラ (ホスト実行可能ファイル: checkpolicycheckmodule 、および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が生成されます。

この画像は、Android 7.x の SELinux ビルド ロジックを示しています。
図1 。 SELinux ビルド ロジック

sepolicyファイルは複数のソース ファイルで構成されます。

  • プレーンテキストのpolicy.conf security_classesinitial_sids*.teファイル、 genfs_contexts 、およびport_contextsをこの順序で連結することによって生成されます。
  • 各ファイル ( security_classesなど) の内容は、 system/sepolicy/およびBOARDS_SEPOLICY_DIRSの下にある同じ名前のファイルを連結したものです。
  • policy.conf構文チェックのために SELinux コンパイラに送信され、デバイス上でsepolicyとしてバイナリ形式にコンパイルされます。
    この画像は、Android 7.x の SELinux ポリシー ファイルを生成するファイルを示しています。
    図2 。 SELinuxポリシーファイル

SELinux ファイル

コンパイル後、7.x 以前を実行している Android デバイスには通常、次の SELinux 関連ファイルが含まれます。

  • selinux_version
  • sepolicy: ポリシー ファイル ( security_classesinitial_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}.cilPRODUCT_PACKAGESに追加します。
  • 製品のマッピング ファイルをインストールするには、必要なマッピング情報を含む cil ファイルを{PRODUCT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cilに配置し、 product_{ver}.cilPRODUCT_PACKAGESに追加します。
  • redbullデバイスのプロダクトパーティションのマッピングファイルを追加するを参照してください。

    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 ポリシー コンポーネントを生成します。手順には次のものが含まれます。

    1. ポリシーを SELinux 共通中間言語 (CIL) 形式に変換します。具体的には次のとおりです。
      1. パブリック プラットフォーム ポリシー (システム + システム拡張 + 製品)
      2. プライベート + パブリック ポリシーの組み合わせ
      3. パブリック + ベンダーおよびBOARD_SEPOLICY_DIRSポリシー
    2. ベンダー ポリシーの一部としてパブリックによって提供されるポリシーのバージョン管理。これは、生成されたパブリック CIL ポリシーを使用して、どの部分をプラットフォーム ポリシーにリンクする属性に変換する必要があるかを、パブリック + ベンダー + BOARD_SEPOLICY_DIRSの組み合わせポリシーに通知することによって行われます。
    3. プラットフォームとベンダー部分をリンクするマッピング ファイルを作成します。最初は、これはパブリック ポリシーのタイプをベンダー ポリシーの対応する属性にリンクするだけです。その後、将来のプラットフォーム バージョンで維持されるファイルの基礎も提供され、このプラットフォーム バージョンを対象とするベンダー ポリシーとの互換性が可能になります。
    4. ポリシー ファイルを結合する (デバイス上のソリューションとプリコンパイルされたソリューションの両方について説明します)。
      1. マッピング、プラットフォーム、ベンダー ポリシーを組み合わせます。
      2. 出力されたバイナリ ポリシー ファイルをコンパイルします。

    プリコンパイルされた SELinux ポリシー

    initが SELinux を有効にする前に、 initパーティション ( systemsystem_extproductvendorおよびodm ) からすべての CIL ファイルを収集し、それらをカーネルにロードできる形式のバイナリ ポリシーにコンパイルします。コンパイルには時間がかかるため (通常は 1 ~ 2 秒)、CIL ファイルはビルド時にプリコンパイルされ、sha256 ハッシュとともに/vendor/etc/selinux/precompiled_sepolicyまたは/odm/etc/selinux/precompiled_sepolicyに配置されます。入力 CIL ファイルの数。実行時に、 initハッシュを比較してポリシー ファイルが更新されたかどうかを確認します。何も変更されていない場合、 initプリコンパイルされたポリシーをロードします。そうでない場合、 initオンザフライでコンパイルし、プリコンパイルされたものの代わりにそれを使用します。

    具体的には、次の条件がすべて満たされる場合に、プリコンパイルされたポリシーが使用されます。ここで、 {partition} 、プリコンパイルされたポリシーが存在するパーティション ( vendorまたはodmのいずれか) を表します。

    • /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の両方が存在しません。あるいは両方が存在し、同一です。

    それらのいずれかが異なる場合、 initデバイス上のコンパイル パスにフォールバックします。詳細についてはsystem/core/init/selinux.cppを参照してください。