SELinux-Richtlinie erstellen

Auf dieser Seite wird beschrieben, wie SELinux-Richtlinien erstellt werden. SELinux-Richtlinien werden aus der Kombination aus AOSP-Kernrichtlinien (Plattform) und gerätespezifischen Richtlinien (Anbieter) erstellt. Beim SELinux-Richtlinien-Build-Ablauf 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 boot.img (für Nicht-A/B-Geräte) oder system.img (für A/B-Geräte) jedes Mal ändern mussten, wenn die Richtlinie geändert wurde.

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

Da modulare SELinux-Richtliniendateien jedoch auf /vendor-Partitionen gespeichert werden, muss der init-Prozess die system- und Anbieterpartitionen früher einbinden, damit er SELinux-Dateien aus diesen Partitionen lesen und mit den SELinux-Kerndateien im Verzeichnis system zusammenführen kann, bevor er sie in den Kernel lädt.

Quelldateien

Die Logik zum Erstellen von SELinux befindet sich in diesen Dateien:

  • external/selinux: Externes SELinux-Projekt, das zum Erstellen von HOST-Befehlszeilenprogrammen zum Kompilieren von SELinux-Richtlinien und ‑Labels verwendet wird.
  • system/sepolicy: Core-Android-SELinux-Richtlinienkonfigurationen, einschließlich Kontexten und Richtliniendateien. Die Hauptlogik für die Erstellung von sepolicy befindet sich ebenfalls hier (system/sepolicy/Android.mk).

Weitere Informationen zu den Dateien in system/sepolicy finden Sie unter Schlüsseldateien.

Android 7.x und niedriger

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

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

Die SELinux-Richtlinie wird durch Kombinieren der AOSP-Kernrichtlinie mit gerätespezifischen Anpassungen erstellt. Die kombinierte Richtlinie wird dann an den Richtlinien-Compiler und verschiedene Prüfungen übergeben. Die gerätespezifische Anpassung erfolgt über die Variable BOARD_SEPOLICY_DIRS, die in der gerätespezifischen Datei Boardconfig.mk definiert ist. Diese globale Build-Variable enthält eine Liste von Verzeichnissen, in denen nach zusätzlichen Richtliniendateien gesucht wird. Die Reihenfolge der Verzeichnisse gibt an, in welcher Reihenfolge gesucht wird.

So könnten beispielsweise ein SoC-Anbieter und ein ODM 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 file_contexts-Dateien in system/sepolicy und BOARD_SEPOLICY_DIRS wird verkettet, um die Datei file_contexts.bin auf dem Gerät zu generieren:

SELinux-Build-Logik für Android 7.x

Abbildung 1: SELinux-Build-Logik.

Die Datei sepolicy besteht aus mehreren Quelldateien:

  • Der Nur-Text policy.conf wird durch Verketten 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 als sepolicy in ein Binärformat kompiliert.

    Dateien, mit 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 Version 7.x und niedriger in der Regel die folgenden SELinux-bezogenen Dateien:

  • selinux_version
  • sepolicy: Binäre Ausgabe 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 Hochfahren 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 der RAM-Disk in den Kernel.
  • Wechselt SELinux in den Erzwingungsmodus.
  • Führt re-exec() aus, um die SELinux-Domainregel auf sich selbst anzuwenden.

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

Android 8.0 oder höher

In Android 8.0 wird die SELinux-Richtlinie in Plattform- und Anbieterkomponenten aufgeteilt, um unabhängige Plattform- und Anbieterrichtlinien-Updates zu ermöglichen und gleichzeitig die Kompatibilität aufrechtzuerhalten.

Die Plattform-SEPolicy ist in private und öffentliche Teile unterteilt, um bestimmte Typen und Attribute an Anbieter von Richtlinien zu exportieren. Die öffentlichen Typen/Attribute der Plattform werden für eine bestimmte Plattformversion garantiert als stabile APIs beibehalten. Die Kompatibilität mit früheren öffentlichen Typen/Attributen der Plattform kann für mehrere Versionen mithilfe von Plattformzuordnungsdateien garantiert werden.

Build-Prozess für Android 8.0

Die SELinux-Richtlinie in Android 8.0 wird durch Kombinieren von Teilen aus /system und /vendor erstellt. Die Logik für die entsprechende Einrichtung befindet sich in /platform/system/sepolicy/Android.bp.

Die Richtlinie ist an den folgenden Stellen verfügbar:

Standort Enthält
system/sepolicy/public Platform sepolicy API
system/sepolicy/private Details zur Plattformimplementierung (für Anbieter nicht relevant)
system/sepolicy/vendor Richtlinien- und Kontextdateien, die Anbieter verwenden können (Anbieter können sie ignorieren)
BOARD_SEPOLICY_DIRS Anbieter-SEPolicy
BOARD_ODM_SEPOLICY_DIRS (Android 9 und höher) ODM-SELinux-Richtlinie
SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS (Android 11 und höher) system_ext sepolicy API
SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS (Android 11 und höher) system_ext Implementierungsdetails (können von Anbietern ignoriert werden)
PRODUCT_PUBLIC_SEPOLICY_DIRS (Android 11 und höher) Product sepolicy API
PRODUCT_PRIVATE_SEPOLICY_DIRS (Android 11 und höher) Details zur Produktimplementierung (können von Anbietern ignoriert werden)

Das Build-System verwendet diese Richtlinie und erstellt die Richtlinienkomponenten system, system_ext, product, vendor und odm auf der entsprechenden Partition. Erforderliche Schritte:

  1. Richtlinien in das SELinux Common Intermediate Language-Format (CIL) konvertieren, insbesondere:
    • Richtlinien für öffentliche Plattformen (system, system_ext, product)
    • Kombinierte private und öffentliche Richtlinie
    • Öffentliche Richtlinien, Anbieterrichtlinien und BOARD_SEPOLICY_DIRS-Richtlinien
  2. Versionieren Sie die von der Öffentlichkeit bereitgestellte Richtlinie als Teil der Anbieterrichtlinie. Verwenden Sie die erstellte öffentliche CIL-Richtlinie, um die kombinierte öffentliche und BOARD_SEPOLICY_DIRS-Richtlinie für Anbieter zu informieren, welche Teile in Attribute umgewandelt werden müssen, die mit der Plattformrichtlinie verknüpft sind.
  3. Erstellen Sie eine Zuordnungsdatei, in der die Plattform- und Anbieterteile verknüpft werden. Anfangs 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 (sowohl On-Device- als auch vorkompilierte Lösungen beschreiben).
    1. Kombinieren Sie die Richtlinien für Mapping, Plattform und Anbieter.
    2. Kompilieren Sie die binäre Ausgaberichtliniendatei.

Öffentliche SEPolicy der Plattform

Die öffentliche SELinux-Richtlinie der Plattform umfasst alles, was unter system/sepolicy/public definiert ist. Die Plattform kann davon ausgehen, dass die unter „Öffentliche Richtlinie“ definierten Typen und Attribute stabile APIs für eine bestimmte Plattformversion sind. Dies ist der Teil der sepolicy, der von der Plattform exportiert wird, auf der Vendor- (d. h. Geräte-)Richtlinienentwickler zusätzliche gerätespezifische Richtlinien schreiben können.

Die Typen werden entsprechend der Version der Richtlinie, für die Anbieterdateien geschrieben werden, versioniert. Diese wird durch die Build-Variable PLATFORM_SEPOLICY_VERSION definiert. Die versionierte öffentliche Richtlinie wird dann in die Händlerrichtlinie und (in ihrer ursprünglichen Form) in die Plattformrichtlinie aufgenommen. Die endgültige Richtlinie umfasst also die private Plattformrichtlinie, die öffentliche SELinux-Richtlinie der aktuellen Plattform, die gerätespezifische Richtlinie und die versionierte öffentliche Richtlinie, die der Plattformversion entspricht, für die die Geräterichtlinie geschrieben wurde.

Plattform-private SELinux-Richtlinie

Die private SELinux-Richtlinie der Plattform umfasst alles, was unter /system/sepolicy/private definiert ist. Dieser Teil der Richtlinie umfasst nur Typen, Berechtigungen und Attribute, die für die Plattformfunktionen erforderlich sind. Diese werden nicht an die Autoren von Anbieter- und Geräterichtlinien exportiert. Richtlinienautoren, die nicht zur Plattform gehören, dürfen ihre Richtlinienerweiterungen nicht auf Typen, Attributen und Regeln basieren, die in der privaten SELinux-Richtlinie der Plattform definiert sind. Außerdem können diese Regeln im Rahmen eines reinen Framework-Updates geändert werden oder verschwinden.

Private Zuordnung auf der Plattform

Die private Plattformzuordnung enthält Richtlinienanweisungen, die die Attribute, die in der öffentlichen Plattformrichtlinie der vorherigen Plattformversionen verfügbar gemacht wurden, den konkreten Typen zuordnen, die in der aktuellen öffentlichen Plattform-SELinux-Richtlinie verwendet werden. So wird sichergestellt, dass die Anbieterrichtlinie, die auf Grundlage der öffentlichen Plattformattribute aus den vorherigen öffentlichen Plattform-SELinux-Versionen geschrieben wurde, weiterhin funktioniert. Die Versionsverwaltung basiert auf der Build-Variablen PLATFORM_SEPOLICY_VERSION, die in AOSP für eine bestimmte Plattformversion festgelegt ist. Für jede frühere Plattformversion, von der erwartet wird, dass diese Plattform die Richtlinie für Anbieter akzeptiert, ist eine separate Zuordnungsdatei vorhanden. Weitere Informationen finden Sie unter Richtlinienkompatibilität.

Android 11 oder höher

In diesem Abschnitt wird beschrieben, wie SELinux-Richtlinien in Android 11 und höher erstellt werden.

system_ext- und Produkt-Selinux-Richtlinien

In Android 11 werden die Richtlinien system_ext und product hinzugefügt. Wie die Plattform-SEPOL-Richtlinie sind die system_ext-Richtlinie und die product-Richtlinie in öffentliche und private Richtlinien unterteilt.

Die öffentliche Richtlinie wird an den Anbieter exportiert. Typen und Attribute werden zu einer stabilen API und in der Händlerrichtlinie kann auf Typen und Attribute in der öffentlichen Richtlinie verwiesen werden. Die Typen werden gemäß PLATFORM_SEPOLICY_VERSION versioniert und die versionierte Richtlinie wird in die Anbieterrichtlinie aufgenommen. Die ursprüngliche Richtlinie ist in jeder Partition von system_ext und product enthalten.

Die private Richtlinie enthält nur system_ext- und product-Typen, Berechtigungen und Attribute, die für die system_ext- und product-Partitionierungsfunktion 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

system_ext und product dürfen ihre zugewiesenen öffentlichen Typen an den Anbieter exportieren. Jeder Partner ist jedoch für die Aufrechterhaltung der Kompatibilität verantwortlich. Zur 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 SELinux-Richtlinie 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 product 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 dann product_{ver}.cil zu PRODUCT_PACKAGES hinzu.

Beispiel für das Hinzufügen einer Zuordnungsdatei für die product-Partition eines Redbull-Geräts.

Vorkompilierte SELinux-Richtlinie

Bevor init SELinux aktiviert, werden alle CIL-Dateien aus Partitionen (system, system_ext, product, vendor und odm) erfasst und in eine binäre Richtlinie kompiliert, die in den Kernel geladen werden kann.init Da die Kompilierung Zeit in Anspruch nimmt (normalerweise 1–2 Sekunden), werden die CIL-Dateien zur Build-Zeit vorkompiliert und zusammen mit den SHA256-Hashes der CIL-Eingabedateien entweder unter /vendor/etc/selinux/precompiled_sepolicy oder /odm/etc/selinux/precompiled_sepolicy platziert. Zur Laufzeit prüft init anhand der Hashes, ob eine der Richtliniendateien aktualisiert wurde. Wenn sich nichts geändert hat, wird die vorkompilierte Richtlinie von init geladen. Andernfalls wird init spontan kompiliert und anstelle der vorkompilierten Version verwendet.

Genauer gesagt wird die vorkompilierte Richtlinie verwendet, wenn alle folgenden Bedingungen erfüllt sind. Dabei steht {partition} für die Partition, in der die vorkompilierte 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 sind vorhanden und 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 sind vorhanden und identisch.

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