Erstellen von SELinux-Richtlinien

In diesem Artikel wird beschrieben, wie die SELinux-Richtlinie erstellt wird. Die SELinux-Richtlinie wird aus der Kombination der Kern-AOSP-Richtlinie (Plattform) und der gerätespezifischen Richtlinie (Anbieter) erstellt. Der SELinux-Richtlinien-Build-Flow für Android 4.4 bis Android 7.0 hat alle sepolicy-Fragmente zusammengeführt und dann monolithische Dateien im Stammverzeichnis generiert. Dies 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) modifizierten.

In Android 8.0 und höher werden Plattform- und Anbieterrichtlinie 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 Plattformaktualisierungen aktualisieren.

Da modularisierte SELinux-Richtliniendateien jedoch auf /vendor -Partitionen gespeichert werden, muss der init -Prozess die System- und Herstellerpartitionen früher mounten, damit er SELinux-Dateien von diesen Partitionen lesen und sie mit SELinux-Kerndateien im Systemverzeichnis zusammenführen kann (bevor sie in der Kern).

Quelldaten

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

  • external/selinux : Externes SELinux-Projekt, das zum Erstellen von HOST-Befehlszeilendienstprogrammen zum Kompilieren von SELinux-Richtlinien und -Labels verwendet wird.
    • external/selinux/libselinux : Android verwendet nur eine Teilmenge des externen libselinux -Projekts zusammen mit einigen Android-spezifischen Anpassungen. Einzelheiten finden Sie unter external/selinux/README.android .
    • external/selinux/libsepol :
      • chkcon : Bestimmen Sie, ob ein Sicherheitskontext für eine bestimmte binäre Richtlinie (ausführbare Hostdatei) gültig ist.
      • libsepol : SELinux-Bibliothek zum Manipulieren binärer Sicherheitsrichtlinien (statische/gemeinsam genutzte Hostbibliothek, statische Zielbibliothek).
    • external/selinux/checkpolicy : SELinux-Richtlinien-Compiler (ausführbare Hostdateien: checkpolicy , checkmodule und dispol ). Hängt von libsepol .
  • system/sepolicy : Grundlegende Android SELinux-Richtlinienkonfigurationen, einschließlich Kontexten und Richtliniendateien. Hier finden Sie auch wichtige sepolicy-Build-Logik ( system/sepolicy/Android.mk ).

Weitere Einzelheiten zu den Dateien in system/sepolicy Implementing SELinux .

Android 7.0 und früher

In diesem Abschnitt wird beschrieben, wie die SELinux-Richtlinie in Android 7.x und früher erstellt wird.

Erstellen von SELinux-Richtlinien

Die SELinux-Richtlinie wird erstellt, indem die Kern-AOSP-Richtlinie mit gerätespezifischen Anpassungen kombiniert wird. Die kombinierte Richtlinie wird dann an den Richtlinienkompilierer und verschiedene Prüfer weitergegeben. 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, die die Reihenfolge angeben, in der nach zusätzlichen Richtliniendateien gesucht werden soll.

Beispielsweise könnten ein SoC-Anbieter und ein ODM jeweils ein Verzeichnis hinzufügen, eines für die SoC-spezifischen Einstellungen und ein weiteres für gerätespezifische 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 file_contexts.bin auf dem Gerät zu generieren:

Dieses Bild zeigt die SELinux-Build-Logik für Android 7.x.
Abbildung 1 . SELinux-Build-Logik

Die sepolicy -Datei besteht aus mehreren Quelldateien:

  • Die Klartext- policy.conf wird generiert, indem die Dateien security_classes , initial_sids , *.te , genfs_contexts und port_contexts in dieser Reihenfolge verkettet werden.
  • 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 als sepolicy auf dem Gerät in das Binärformat kompiliert.
    Dieses Bild zeigt die Dateien, die die SELinux-Richtliniendatei für Android 7.x generieren.
    Abbildung 2 . SELinux-Richtliniendatei

SELinux-Dateien

Nach dem Kompilieren enthalten Android-Geräte mit 7.x und früher normalerweise 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 Einzelheiten finden Sie unter Implementieren von SELinux .

SELinux-Initialisierung

Wenn das System hochfährt, befindet sich SELinux im Permissive-Modus (und nicht im Enforcing-Modus). Der Init-Prozess führt die folgenden Aufgaben aus:

  • Lädt sepolicy Dateien von der Ramdisk in den Kernel durch /sys/fs/selinux/load .
  • Schaltet SELinux in den Erzwingungsmodus.
  • Führt re-exec() aus, um die SELinux-Domänenregel auf sich selbst anzuwenden.

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

Android 8.0 und höher

In Android 8.0 ist die SELinux-Richtlinie in Plattform- und Anbieterkomponenten aufgeteilt, um unabhängige Plattform-/Anbieter-Richtlinienaktualisierungen zu ermöglichen und gleichzeitig die Kompatibilität aufrechtzuerhalten.

Die Plattform-Sepolicy ist weiter in private und öffentliche Plattformteile unterteilt, um bestimmte Typen und Attribute an Anbieterrichtlinienautoren zu exportieren. Die öffentlichen Typen/Attribute der Plattform werden garantiert als stabile APIs für eine bestimmte Plattformversion beibehalten. Die Kompatibilität mit öffentlichen Typen/Attributen früherer Plattformen kann für mehrere Versionen unter Verwendung von Plattformzuordnungsdateien garantiert werden.

Plattform Public Separation

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

Typen werden gemäß der Version der Richtlinie versioniert, für die Herstellerdateien geschrieben werden, definiert durch die Build-Variable PLATFORM_SEPOLICY_VERSION . Die versionierte öffentliche Richtlinie wird dann in die Anbieterrichtlinie und (in ihrer ursprünglichen Form) in die Plattformrichtlinie aufgenommen. Somit umfasst die endgültige Richtlinie die Richtlinie für private Plattformen, die öffentliche 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.

Private Trennungsrichtlinie der Plattform

Die Plattform private sepolicy umfasst alles, was unter /system/sepolicy/private definiert ist. Dieser Teil der Richtlinie bildet plattformspezifische Typen, Berechtigungen und Attribute, die für die Plattformfunktionalität erforderlich sind. Diese werden nicht an die Ersteller von vendor/device exportiert. Nicht-Plattform-Richtlinienautoren dürfen ihre Richtlinienerweiterungen nicht auf der Grundlage von Typen/Attributen/Regeln schreiben, die in der Plattform-Private-Se-Policy definiert sind. Darüber hinaus dürfen diese Regeln geändert werden oder im Rahmen eines Nur-Framework-Updates verschwinden.

Private Zuordnung der Plattform

Die Plattform-Privat-Zuordnung enthält Richtlinienanweisungen, die die Attribute, die in der öffentlichen Plattform-Richtlinie der vorherigen Plattformversionen offengelegt wurden, auf die konkreten Typen abbilden, die in der aktuellen öffentlichen Plattform-Richtlinie verwendet werden. Dadurch wird sichergestellt, dass die Anbieterrichtlinie, die basierend auf den öffentlichen Plattformattributen der vorherigen öffentlichen Plattformversion(en) geschrieben wurde, weiterhin funktioniert. Die Versionierung 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 diese Plattform die Herstellerrichtlinie akzeptieren soll, ist eine separate Zuordnungsdatei vorhanden. Weitere Einzelheiten finden Sie unter Kompatibilität .

Android 11 und höher

system_ext und Produkt sepolicy

In Android 11 werden system_ext-Richtlinie und Produktrichtlinie hinzugefügt. Wie die Plattform sepolicy werden system_ext policy und product policy in public policy und private policy unterteilt.

Die öffentliche Ordnung 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. Typen werden gemäß PLATFORM_SEPOLICY_VERSION versioniert, und die versionierte Richtlinie wird in die Anbieterrichtlinie aufgenommen. Die ursprüngliche Richtlinie ist sowohl in system_ext als auch in der Produktpartition enthalten.

Die private Richtlinie enthält nur system_ext- und product-only-Typen, Berechtigungen und Attribute, die für die Funktionalität von system_ext und Produktpartitionen erforderlich sind. Private Richtlinien sind für den Anbieter unsichtbar, was bedeutet, dass diese Regeln intern sind und geändert werden dürfen.

system_ext und Produktzuordnung

system_ext und product dürfen ihre ausgewiesenen öffentlichen Typen an den Anbieter exportieren. Die Verantwortung für die Aufrechterhaltung der Kompatibilität liegt jedoch bei jedem Partner. Aus Kompatibilitätsgründen können Partner ihre eigenen Zuordnungsdateien bereitstellen, die die versionierten Attribute früherer Versionen konkreten Typen zuordnen, die in der aktuellen öffentlichen Richtlinie verwendet werden.

  • Um eine Zuordnungsdatei für system_ext zu installieren, platzieren Sie eine cil-Datei mit den gewünschten Zuordnungsinformationen in {SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil und fügen Sie dann system_ext_{ver}.cil zu PRODUCT_PACKAGES .
  • Um eine Zuordnungsdatei für das Produkt zu installieren, platzieren Sie eine cil-Datei mit den gewünschten Zuordnungsinformationen in {PRODUCT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil und fügen Sie dann product_{ver}.cil zu PRODUCT_PACKAGES .
  • Siehe ein Beispiel , das eine Zuordnungsdatei der Produktpartition des Redbull-Geräts hinzufügt.

    Erstellen von SELinux-Richtlinien

    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.mk .

    Die Richtlinie ist an folgenden Orten vorhanden:

    Ort 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 bei Bedarf ignorieren)
    BOARD_SEPOLICY_DIRS Anbietertrennung
    BOARD_ODM_SEPOLICY_DIRS (Android 9 und höher) Odm Trennung
    SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS (Android 11 und höher) Die sepolicy-API von System_ext
    SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS (Android 11 und höher) System_ext-Implementierungsdetails (Anbieter können ignorieren)
    PRODUCT_PUBLIC_SEPOLICY_DIRS (Android 11 und höher) Die sepolicy-API des Produkts
    PRODUCT_PRIVATE_SEPOLICY_DIRS (Android 11 und höher) Details zur Produktimplementierung (Anbieter können ignorieren)

    Das Build-System übernimmt diese Richtlinie und erstellt die Richtlinienkomponenten System, System_ext, Produkt, Anbieter und ODM auf der entsprechenden Partition. Zu den Schritten gehören:

    1. Konvertieren von Richtlinien in das SELinux Common Intermediate Language (CIL)-Format, insbesondere:
      1. öffentliche Plattformrichtlinie (system + system_ext + product)
      2. kombinierte private + öffentliche Politik
      3. öffentliche + Anbieter- und BOARD_SEPOLICY_DIRS Richtlinie
    2. Versionierung der Richtlinie, die öffentlich als Teil der Anbieterrichtlinie bereitgestellt wird. Dies erfolgt durch Verwenden der erstellten öffentlichen CIL-Richtlinie, um die kombinierte Richtlinie öffentlich + Anbieter + BOARD_SEPOLICY_DIRS 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. Dabei werden zunächst nur die Typen aus der öffentlichen Richtlinie mit den entsprechenden Attributen in der Herstellerrichtlinie verknüpft; Später wird es auch die Grundlage für die Datei liefern, die in zukünftigen Plattformversionen verwaltet wird, wodurch die Kompatibilität mit der Herstellerrichtlinie ermöglicht wird, die auf diese Plattformversion abzielt.
    4. Kombinieren von Richtliniendateien (beschreiben Sie sowohl geräteinterne als auch vorkompilierte Lösungen).
      1. Kombinieren Sie Zuordnungs-, Plattform- und Anbieterrichtlinien.
      2. Kompilieren Sie die binäre Richtlinienausgabedatei.

    Vorkompilierte SELinux-Richtlinie

    Bevor init SELinux einschaltet, sammelt init alle CIL-Dateien von Partitionen ( system , system_ext , product , vendor und odm ) und kompiliert sie in binäre Richtlinien, 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 Erstellungszeit vorkompiliert und zusammen mit den sha256-Hashes entweder unter /vendor/etc/selinux/precompiled_sepolicy oder /odm/etc/selinux/precompiled_sepolicy der Eingabe-CIL-Dateien. Zur Laufzeit prüft init , ob eine der Richtliniendateien aktualisiert wurde, indem es die Hashes vergleicht. Wenn sich nichts geändert hat, lädt init die vorkompilierte Richtlinie. Wenn nicht, kompiliert init on the fly und verwendet es anstelle des vorkompilierten.

    Genauer gesagt wird eine vorkompilierte Richtlinie verwendet, wenn alle der folgenden Bedingungen erfüllt sind. Hier stellt {partition} die Partition dar, 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 existieren und sind 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 existieren nicht. 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 existieren nicht. Oder beide existieren und sind identisch.

    Wenn sich einer von ihnen unterscheidet, init auf den Kompilierungspfad auf dem Gerät zurück. Siehe system/core/init/selinux.cpp für weitere Details.