SELinux-Richtlinie erstellen

Auf dieser Seite erfahren Sie, wie SELinux-Richtlinien erstellt werden. Die SELinux-Richtlinie besteht aus einer Kombination aus der AOSP-Kernrichtlinie (Plattform) und der gerätespezifischen Richtlinie (Anbieter). Beim SELinux-Richtlinien-Build-Vorgang für Android 4.4 bis Android 7.0 wurden alle SEPolicy-Fragmente zusammengeführt und dann monolithische Dateien im Stammverzeichnis generiert. Das bedeutete, dass SoC-Anbieter und ODM-Hersteller jedes Mal, wenn die Richtlinie geändert wurde, boot.img (für Nicht-A/B-Geräte) oder system.img (für A/B-Geräte) ändern mussten.

Unter Android 8.0 und höher werden Plattform- und Anbieterrichtlinien separat erstellt. SOCs und OEMs können ihre Teile der Richtlinie aktualisieren, ihre Images erstellen (z. B. vendor.img und boot.img) und diese Images dann unabhängig von Plattformupdates aktualisieren.

Da modulare SELinux-Richtliniendateien jedoch auf /vendor-Partitionen gespeichert sind, müssen die System- und Anbieterpartitionen vom init-Prozess früher bereitgestellt werden, damit er SELinux-Dateien aus diesen Partitionen lesen und mit den SELinux-Kerndateien im Systemverzeichnis zusammenführen kann, bevor sie in den Kernel geladen werden.

Quelldateien

Die Logik zum Erstellen von SELinux befindet sich in den folgenden Dateien:

  • external/selinux: Externes SELinux-Projekt, mit dem HOST-Befehlszeilen-Dienstprogramme zum Kompilieren von SELinux-Richtlinien und ‑Labels erstellt werden.
    • external/selinux/libselinux: Android verwendet nur einen Teil des externen libselinux-Projekts sowie einige Android-spezifische Anpassungen. Weitere Informationen finden Sie unter external/selinux/README.android.
    • external/selinux/libsepol:
      • chkcon: Prüft, ob ein Sicherheitskontext für eine bestimmte Binärrichtlinie (Hostausführbare Datei) gültig ist.
      • libsepol: SELinux-Bibliothek zum Manipulieren von Sicherheitsrichtlinien für Binärdateien (statische/freigegebene Hostbibliothek, statische Zielbibliothek).
    • external/selinux/checkpolicy: SELinux-Richtliniencompiler (Hostausführbare Dateien: checkpolicy, checkmodule und dispol). Abhängig von libsepol.
  • system/sepolicy: Grundlegende Android-SELinux-Richtlinienkonfigurationen, einschließlich Kontexten und Richtliniendateien. Die Hauptlogik für die Erstellung von SEPolicy-Richtlinien ist hier ebenfalls zu finden (system/sepolicy/Android.mk).

Weitere Informationen zu den Dateien in system/sepolicy finden Sie unter Implementing SELinux (SELinux implementieren).

Android 7.x und niedriger

In diesem Abschnitt wird beschrieben, wie SELinux-Richtlinien in Android 7.x und niedriger implementiert sind.

Build-Prozess für Android 7.x und niedriger

Die SELinux-Richtlinie wird durch Kombination der AOSP-Kernrichtlinie mit gerätespezifischen Anpassungen erstellt. Die kombinierte Richtlinie wird dann an den Richtliniencompiler und verschiedene Prüfprogramme übergeben. Die gerätespezifische Anpassung erfolgt über die Variable BOARD_SEPOLICY_DIRS, die in der gerätespezifischen Datei Boardconfig.mk definiert ist. Diese globale Buildvariable enthält eine Liste von Verzeichnissen, die die Reihenfolge angeben, in der nach zusätzlichen Richtliniendateien gesucht werden soll.

Ein SoC-Anbieter und ein ODM können beispielsweise jeweils ein Verzeichnis hinzufügen, eines für die SoC-spezifischen Einstellungen und eines für die gerätespezifischen Einstellungen, um die endgültigen SELinux-Konfigurationen für ein bestimmtes Gerät zu generieren:

  • BOARD_SEPOLICY_DIRS += device/SOC/common/sepolicy
  • BOARD_SEPOLICY_DIRS += device/SoC/DEVICE/sepolicy

Der Inhalt der Dateien „file_contexts“ in system/sepolicy und BOARD_SEPOLICY_DIRS wird zusammengeführt, um die file_contexts.bin auf dem Gerät zu generieren:

Dieses Bild zeigt die SELinux-Buildlogik für Android 7.x.

Abbildung 1: SELinux-Buildlogik

Die sepolicy-Datei besteht aus mehreren Quelldateien:

  • Der Nur-Text policy.conf wird durch Zusammenführen der Dateien security_classes, initial_sids, *.te, genfs_contexts und port_contexts in dieser Reihenfolge generiert.
  • Der Inhalt jeder Datei (z. B. security_classes) ist die Verkettung der Dateien mit demselben Namen unter system/sepolicy/ und BOARDS_SEPOLICY_DIRS.
  • Die policy.conf wird zur Syntaxprüfung an den SELinux-Compiler gesendet und auf dem Gerät in das Binärformat sepolicy kompiliert.
    Auf diesem Bild sind die Dateien zu sehen, aus denen die SELinux-Richtliniendatei für Android 7.x generiert wird.

    Abbildung 2: SELinux-Richtliniendatei.

SELinux-Dateien

Nach der Kompilierung enthalten Android-Geräte mit Android 7.x und niedriger in der Regel die folgenden SELinux-bezogenen Dateien:

  • selinux_version
  • sepolicy: Binärausgabe nach dem Kombinieren von Richtliniendateien (z. B. security_classes, initial_sids und *.te)
  • file_contexts
  • property_contexts
  • seapp_contexts
  • service_contexts
  • system/etc/mac_permissions.xml

Weitere Informationen finden Sie unter SELinux implementieren.

SELinux-Initialisierung

Beim Starten des Systems befindet sich SELinux im permissiven Modus und nicht im Erzwingungsmodus. Der init-Prozess führt die folgenden Aufgaben aus:

  • Lädt sepolicy-Dateien über /sys/fs/selinux/load aus dem RAM-Disk in den Kernel.
  • SELinux wird in den Erzwingungsmodus versetzt.
  • Führt re-exec() aus, um die SELinux-Domainregel auf sich selbst anzuwenden.

Um die Bootzeit zu verkürzen, führen Sie die re-exec() für den init-Prozess so bald wie möglich aus.

Android 8.0 oder höher

In Android 8.0 ist die SELinux-Richtlinie in Plattform- und Anbieterkomponenten unterteilt, um unabhängige Plattform-/Anbieterrichtlinienupdates bei gleichzeitiger Beibehaltung der Kompatibilität zu ermöglichen.

Die Plattform-SEPolicy wird weiter in „platform private“ (für die Plattform privat) und „platform public“ (für die Plattform öffentlich) unterteilt, um bestimmte Typen und Attribute an die Richtlinienschreiber von Anbietern zu exportieren. Die öffentlichen Typen/Attribute der Plattform werden garantiert als stabile APIs für eine bestimmte Plattformversion gepflegt. Die Kompatibilität mit früheren öffentlichen Typen/Attributen der Plattform kann für mehrere Versionen mithilfe von Plattformzuordnungsdateien gewährleistet werden.

Build-Prozess für Android 8.0

Die SELinux-Richtlinie in Android 8.0 wird durch die Kombination von Teilen aus /system und /vendor erstellt. Die Logik für die entsprechende Einrichtung findest du unter /platform/system/sepolicy/Android.mk.

Die Richtlinie ist an den folgenden Stellen verfügbar:

Standort Enthält
system/sepolicy/public Die Sepolicy API der Plattform
system/sepolicy/private Details zur Plattformimplementierung (Anbieter können ignorieren)
system/sepolicy/vendor Richtlinien- und Kontextdateien, die Anbieter verwenden können (Anbieter können sie bei Bedarf ignorieren)
BOARD_SEPOLICY_DIRS Anbieter-SEPolicy
BOARD_ODM_SEPOLICY_DIRS (Android 9 und höher) Odm sepolicy
SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS (Android 11 und höher) Sepolicy API von System_ext
SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS (Android 11 und höher) Implementierungsdetails für „System_ext“ (Anbieter können ignorieren)
PRODUCT_PUBLIC_SEPOLICY_DIRS (Android 11 und höher) Sepolicy API des Produkts
PRODUCT_PRIVATE_SEPOLICY_DIRS (Android 11 und höher) Details zur Produktimplementierung (Anbieter können ignorieren)

Das Build-System verwendet diese Richtlinie und generiert System-, System_ext-, Produkt-, Anbieter- und ODM-Richtlinienkomponenten in der entsprechenden Partition. Dazu gehören folgende Schritte:

  1. Richtlinien in das SELinux Common Intermediate Language (CIL)-Format konvertieren, insbesondere:
    1. Richtlinie für öffentliche Plattformen (system + system_ext + product)
    2. Kombinierte Richtlinie für private und öffentliche Richtlinien
    3. public + vendor and BOARD_SEPOLICY_DIRS policy
  2. Versionierung der vom Anbieter als Teil der Anbieterrichtlinie bereitgestellten Richtlinie. Dazu wird die erstellte öffentliche CIL-Richtlinie verwendet, um die kombinierte öffentliche + Anbieter- + BOARD_SEPOLICY_DIRS-Richtlinie darüber zu informieren, welche Teile in Attribute umgewandelt werden müssen, die mit der Plattformrichtlinie verknüpft werden.
  3. Erstellen einer Zuordnungsdatei, die die Plattform- und Anbieterteile verknüpft. Zunächst werden nur die Typen aus der öffentlichen Richtlinie mit den entsprechenden Attributen in der Anbieterrichtlinie verknüpft. Später bildet sie auch die Grundlage für die Datei, die in zukünftigen Plattformversionen verwaltet wird, und ermöglicht so die Kompatibilität mit der Anbieterrichtlinie, die auf diese Plattformversion ausgerichtet ist.
  4. Richtliniendateien kombinieren (beschreiben Sie sowohl On-Device- als auch vorkompilierte Lösungen).
    1. Zuordnungs-, Plattform- und Anbieterrichtlinien kombinieren
    2. Kompilieren Sie die Ausgabedatei für die Binärrichtlinie.

Öffentliche SEPolicy der Plattform

Die öffentliche SEPolicy der Plattform umfasst alles, was unter system/sepolicy/public definiert ist. Die Plattform kann davon ausgehen, dass die gemäß den öffentlichen Richtlinien definierten Typen und Attribute stabile APIs für eine bestimmte Plattformversion sind. Dieser Teil der SEPolicy wird von der Plattform exportiert, auf der Anbieterrichtlinien (d. h. Geräterichtlinien) von Entwicklern erstellt werden können.

Die Versionierung von Typen erfolgt gemäß der Version der Richtlinie, die für die Erstellung von Anbieterdateien verwendet wird. Diese wird durch die Buildvariable PLATFORM_SEPOLICY_VERSION definiert. Die versionierte öffentliche Richtlinie wird dann in die Anbieterrichtlinie und (in ihrer ursprünglichen Form) in die Plattformrichtlinie aufgenommen. Die endgültige Richtlinie umfasst daher die private Plattformrichtlinie, die öffentliche SEPolicy der aktuellen Plattform, die gerätespezifische Richtlinie und die versionierte öffentliche Richtlinie, die der Plattformversion entspricht, für die die Geräterichtlinie geschrieben wurde.

Plattformspezifische SEPolicy

Die private SEPolicy der Plattform umfasst alles, was unter /system/sepolicy/private definiert ist. Dieser Teil der Richtlinie umfasst nur für die Plattform erforderliche Typen, Berechtigungen und Attribute. Sie werden nicht in die vendor/device-Richtlinienvorlagen exportiert. Autoren von Richtlinien, die nicht zur Plattform gehören, dürfen ihre Richtlinienerweiterungen nicht auf Grundlage von Typen, Attributen oder Regeln schreiben, die in der privaten SEPolicy der Plattform definiert sind. Außerdem können diese Regeln geändert werden oder im Rahmen eines Updates nur für das Framework verschwinden.

Private Kartierung der Plattform

Die private Zuordnung der Plattform enthält Richtlinienbeschreibungen, die die Attribute, die in der öffentlichen Plattformrichtlinie der vorherigen Plattformversionen offengelegt wurden, den konkreten Typen zuordnen, die in der aktuellen öffentlichen Plattform-Sicherheitsrichtlinie verwendet werden. So wird sichergestellt, dass Anbieterrichtlinien, die auf Grundlage der öffentlichen Plattformattribute der vorherigen öffentlichen SEPolicy-Versionen geschrieben wurden, weiterhin funktionieren. Die Versionierung basiert auf der Buildvariablen PLATFORM_SEPOLICY_VERSION, die in AOSP für eine bestimmte Plattformversion festgelegt ist. Für jede vorherige Plattformversion, von der diese Plattform voraussichtlich die Anbieterrichtlinien akzeptiert, gibt es eine separate Zuordnungsdatei. Weitere Informationen finden Sie unter Kompatibilität.

Android 11 oder höher

system_ext und product sepolicy

Unter Android 11 werden die Richtlinie „system_ext“ und die Produktrichtlinie hinzugefügt. Wie die Plattformrichtlinie sind auch die system_ext-Richtlinie und die Produktrichtlinie in öffentliche und private Richtlinien unterteilt.

Die öffentliche Richtlinie wird an den Anbieter exportiert. Typen und Attribute werden zu einer stabilen API und die Anbieterrichtlinie kann sich auf Typen und Attribute in der öffentlichen Richtlinie beziehen. Die Typen werden gemäß PLATFORM_SEPOLICY_VERSION versioniert und die Versionsrichtlinie ist in der Anbieterrichtlinie enthalten. Die ursprüngliche Richtlinie ist in jeder system_ext- und Produktpartition enthalten.

Die private Richtlinie enthält nur für system_ext und nur für Produkte geltende Typen, Berechtigungen und Attribute, die für die Funktionalität der system_ext- und Produktpartitionen erforderlich sind. Die private Richtlinie ist für den Anbieter nicht sichtbar. Das bedeutet, dass diese Regeln intern sind und geändert werden dürfen.

system_ext und Produktzuordnung

Für „system_ext“ und „product“ ist es zulässig, die angegebenen öffentlichen Typen an „vendor“ zu exportieren. Die Verantwortung für die Kompatibilität liegt jedoch bei jedem Partner. Für die Kompatibilität können Partner eigene Zuordnungsdateien bereitstellen, in denen die versionierten Attribute früherer Versionen konkreten Typen zugeordnet werden, die in der aktuellen öffentlichen SEPolicy verwendet werden.

  • Wenn Sie eine Zuordnungsdatei für „system_ext“ installieren möchten, legen Sie eine CIL-Datei mit den gewünschten Zuordnungsinformationen in {SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil ab und fügen Sie dann system_ext_{ver}.cil zu PRODUCT_PACKAGES hinzu.
  • Wenn Sie eine Zuordnungsdatei für ein Produkt installieren möchten, legen Sie eine CIL-Datei mit den gewünschten Zuordnungsinformationen in {PRODUCT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil ab und fügen Sie product_{ver}.cil zu PRODUCT_PACKAGES hinzu.

In diesem Beispiel wird eine Zuordnungsdatei für die Produktpartition des Redbull-Geräts hinzugefügt.

Vorkompilierte SELinux-Richtlinie

Bevor init SELinux aktiviert, sammelt init alle CIL-Dateien aus Partitionen (system, system_ext, product, vendor und odm) und kompiliert sie in eine binäre Richtlinie, das Format, das in den Kernel geladen werden kann. Da die Kompilierung einige Zeit in Anspruch nimmt (normalerweise 1–2 Sekunden), werden die CIL-Dateien zur Buildzeit vorab kompiliert und zusammen mit den SHA256-Hashes der Eingabe-CIL-Dateien entweder unter /vendor/etc/selinux/precompiled_sepolicy oder /odm/etc/selinux/precompiled_sepolicy abgelegt. Zur Laufzeit prüft init, ob eine der Richtliniendateien aktualisiert wurde, indem die Hash-Werte verglichen werden. Wenn sich nichts geändert hat, lädt init die vorab kompilierte Richtlinie. Andernfalls wird init „on the fly“ kompiliert und anstelle der vorab kompilierten Version verwendet.

Genauer gesagt wird die vorab kompilierte Richtlinie verwendet, wenn alle folgenden Bedingungen erfüllt sind. Hier steht {partition} für die Partition, in der die vorab kompilierte Richtlinie vorhanden ist: entweder vendor oder odm.

  • Sowohl /system/etc/selinux/plat_sepolicy_and_mapping.sha256 als auch /{partition}/etc/selinux/precompiled_sepolicy.plat_sepolicy_and_mapping.sha256 sind vorhanden und identisch.
  • Sowohl /system_ext/etc/selinux/system_ext_sepolicy_and_mapping.sha256 als auch /{partition}/etc/selinux/precompiled_sepolicy.system_ext_sepolicy_and_mapping.sha256 sind nicht vorhanden. Oder beide existieren und sind identisch.
  • Sowohl /product/etc/selinux/product_sepolicy_and_mapping.sha256 als auch /{partition}/etc/selinux/precompiled_sepolicy.product_sepolicy_and_mapping.sha256 sind nicht vorhanden. Oder beide existieren und sind identisch.

Wenn sich einer davon unterscheidet, greift init auf den Kompilierungspfad auf dem Gerät zurück. Weitere Informationen finden Sie unter system/core/init/selinux.cpp.