Erstellen einer SELinux-Richtlinie

In diesem Artikel wird erläutert, wie die SELinux-Richtlinie erstellt wird. Die SELinux-Richtlinie wird aus der Kombination der AOSP-Kernrichtlinie (Plattform) und der gerätespezifischen Richtlinie (Anbieter) erstellt. Der SELinux-Richtlinien-Build-Flow für Android 4.4 bis Android 7.0 führte alle Sepolicy-Fragmente zusammen und generierte dann monolithische Dateien im Stammverzeichnis. Dies bedeutete, dass SoC-Anbieter und ODM-Hersteller bei jeder Änderung der Richtlinie boot.img (für Nicht-A/B-Geräte) oder system.img (für A/B-Geräte) änderten.

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 erstellen (z. vendor.img und boot.img ) 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 den SELinux-Kerndateien im Systemverzeichnis zusammenführen kann (bevor er sie in lädt). der Kernel).

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ärrichtlinie (ausführbare Hostdatei) gültig ist.
      • libsepol : SELinux-Bibliothek zur Manipulation binärer Sicherheitsrichtlinien (statische Host-/gemeinsam genutzte Bibliothek, statische Zielbibliothek).
    • external/selinux/checkpolicy : SELinux-Richtlinien-Compiler (ausführbare Hostdateien: checkpolicy , checkmodule und dispol ). Hängt von libsepol ab.
  • system/sepolicy : Kernrichtlinienkonfigurationen für Android SELinux, einschließlich Kontexten und Richtliniendateien. Hier finden Sie auch die wichtigste Sepolicy-Build-Logik ( system/sepolicy/Android.mk ).

Weitere Einzelheiten zu den Dateien finden Sie unter system/sepolicy Implementing SELinux .

Android 7.0 und früher

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

Erstellen einer SELinux-Richtlinie

Die SELinux-Richtlinie wird durch die Kombination der AOSP-Kernrichtlinie mit gerätespezifischen Anpassungen erstellt. Die kombinierte Richtlinie wird dann an den Richtlinien-Compiler und verschiedene Prüfer ü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, 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 die 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 Nur-Text policy.conf wird durch Verketten von security_classes , initial_sids , *.te -Dateien, 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 als sepolicy auf dem Gerät in ein Binärformat kompiliert.
    Dieses Bild zeigt die Dateien, die die SELinux-Richtliniendatei für Android 7.x generieren.
    Figur 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ä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 Einzelheiten finden Sie unter Implementieren von SELinux .

SELinux-Initialisierung

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

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

Um die Startzeit zu verkürzen, führen Sie so schnell wie möglich re-exec() für den 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-/Anbieterrichtlinienaktualisierungen zu ermöglichen und gleichzeitig die Kompatibilität aufrechtzuerhalten.

Die Plattform-Separatrichtlinie ist weiter in einen privaten und einen öffentlichen Teil der Plattform unterteilt, um bestimmte Typen und Attribute an Anbieter-Richtlinienautoren zu exportieren. Es wird garantiert, dass die öffentlichen Typen/Attribute der Plattform als stabile APIs für eine bestimmte Plattformversion beibehalten werden. Die Kompatibilität mit früheren öffentlichen Typen/Attributen der Plattform kann für mehrere Versionen mithilfe von Plattformzuordnungsdateien gewährleistet werden.

Öffentliche Politik der Plattform

Die Plattform public sepolicy umfasst alles, was unter system/sepolicy/public definiert ist. Die Plattform kann davon ausgehen, dass es sich bei den in der öffentlichen Richtlinie definierten Typen und Attributen um stabile APIs für eine bestimmte Plattformversion handelt. Dies ist der Teil der Sepolicy, der von der Plattform exportiert wird, auf der Entwickler von Anbieterrichtlinien (d. h. Geräterichtlinien) zusätzliche gerätespezifische Richtlinien schreiben können.

Typen werden entsprechend der Version der Richtlinie versioniert, gegen 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 private Plattformrichtlinie, die öffentliche Sep-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 Separierung der Plattform

Die private Sepolicy der Plattform 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 der vendor/device exportiert. Nicht-Plattform-Richtlinienautoren dürfen ihre Richtlinienerweiterungen nicht auf der Grundlage von Typen/Attributen/Regeln schreiben, die in der privaten Sepolicy der Plattform definiert sind. Darüber hinaus dürfen diese Regeln im Rahmen eines reinen Framework-Updates geändert werden oder verschwinden.

Private Plattformzuordnung

Die private Plattformzuordnung umfasst Richtlinienanweisungen, die die in der öffentlichen Plattformrichtlinie der vorherigen Plattformversionen offengelegten Attribute den konkreten Typen zuordnen, die in der aktuellen öffentlichen Plattformrichtlinie verwendet werden. Dadurch wird sichergestellt, dass die Anbieterrichtlinie, die auf der Grundlage der öffentlichen Plattformattribute der vorherigen öffentlichen Plattform-Sepolicy-Version(en) geschrieben wurde, weiterhin funktioniert. Die Versionierung basiert auf der Build-Variable PLATFORM_SEPOLICY_VERSION , die in AOSP für eine bestimmte Plattformversion festgelegt ist. Für jede vorherige Plattformversion, von der aus diese Plattform die Herstellerrichtlinien akzeptieren soll, ist eine separate Zuordnungsdatei vorhanden. Weitere Einzelheiten finden Sie unter Kompatibilität .

Android 11 und höher

system_ext und Produkttrennrichtlinie

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

Die öffentliche Ordnung wird an den Anbieter exportiert. Typen und Attribute werden zu einer stabilen API, und die Anbieterrichtlinie kann auf Typen und Attribute in der öffentlichen Richtlinie verweisen. Typen werden gemäß PLATFORM_SEPOLICY_VERSION versioniert und die versionierte Richtlinie ist in der Anbieterrichtlinie enthalten. Die ursprüngliche Richtlinie ist sowohl in system_ext als auch in der Produktpartition enthalten.

Die private Richtlinie enthält Nur-System_Ext- und Nur-Produkt-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 designierten ö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 Sepolicy 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 hinzu.
  • 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 hinzu.
  • Sehen Sie sich ein Beispiel an, das eine Zuordnungsdatei der Produktpartition des Redbull-Geräts hinzufügt.

    Erstellen einer SELinux-Richtlinie

    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 befindet sich in /platform/system/sepolicy/Android.mk .

    Die Richtlinie ist an den folgenden Orten vorhanden:

    Standort Enthält
    system/sepolicy/public Die Sepolicy-API der Plattform
    system/sepolicy/private Details zur Plattformimplementierung (Anbieter können dies ignorieren)
    system/sepolicy/vendor Richtlinien- und Kontextdateien, die Anbieter verwenden können (Anbieter können diese bei Bedarf ignorieren)
    BOARD_SEPOLICY_DIRS Anbieter-Separatpolitik
    BOARD_ODM_SEPOLICY_DIRS (Android 9 und höher) ODM-Separatpolitik
    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) Details zur System_ext-Implementierung (Anbieter können sie 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 dies ignorieren)

    Das Build-System übernimmt diese Richtlinie und erstellt System-, system_ext-, Produkt-, Anbieter- und ODM-Richtlinienkomponenten 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 + Produkt)
      2. kombinierte private + öffentliche Politik
      3. public + Vendor und BOARD_SEPOLICY_DIRS -Richtlinie
    2. Versionierung der von der Öffentlichkeit bereitgestellten Richtlinie als Teil der Anbieterrichtlinie. Dies geschieht durch Verwendung der erstellten öffentlichen CIL-Richtlinie, um die kombinierte Richtlinie aus Öffentlichkeit, Anbieter und 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 Anbieterrichtlinie verknüpft; Später wird es auch die Grundlage für die Datei bilden, die in zukünftigen Plattformversionen verwaltet wird, und so die Kompatibilität mit den Herstellerrichtlinien für diese Plattformversion ermöglichen.
    4. Kombinieren von Richtliniendateien (beschreiben Sie sowohl geräteinterne als auch vorkompilierte Lösungen).
      1. Kombinieren Sie Mapping-, Plattform- und Anbieterrichtlinien.
      2. Kompilieren Sie die Ausgabe-Binärrichtliniendatei.

    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 die Binärrichtlinie, 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 abgelegt der eingegebenen 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 es im laufenden Betrieb 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 davon unterscheidet, greift init auf den Kompilierungspfad auf dem Gerät zurück. Weitere Informationen finden Sie system/core/init/selinux.cpp .