Richtlinienkompatibilität

Auf dieser Seite wird beschrieben, wie Android mit Problemen bei der Richtlinienkompatibilität bei Over-the-Air-Updates (OTA) der Plattform umgeht, bei denen sich neue SELinux-Einstellungen der Plattform von alten SELinux-Einstellungen des Anbieters unterscheiden können.

Eigentum und Kennzeichnung von Objekten

Das Eigentum muss für jedes Objekt eindeutig definiert sein, damit die Richtlinien für Plattform und Anbieter getrennt bleiben. Wenn beispielsweise die Richtlinien-Labels des Anbieters /dev/foo und die Richtlinien-Labels der Plattform /dev/foo in einem nachfolgenden OTA sind, kann es zu undefiniertem Verhalten wie einer unerwarteten Ablehnung oder, noch schlimmer, einem Boot-Fehler kommen. Bei SELinux äußert sich dies als Labeling-Konflikt. Der Geräteknoten kann nur ein Label haben, das auf das zuletzt angewendete Label verweist. Daraus ergeben sich folgende Konsequenzen:

  • Prozesse, die Zugriff benötigen auf das Label, das nicht angewendet werden konnte, verlieren den Zugriff auf die Ressource.
  • Prozesse, die auf die Datei zugreifen, funktionieren möglicherweise nicht mehr, weil der falsche Geräteknoten erstellt wurde.

Kollisionen zwischen Plattform- und Anbieterlabels können für jedes Objekt mit einem SELinux-Label auftreten, einschließlich Eigenschaften, Dienste, Prozesse, Dateien und Sockets. Um diese Probleme zu vermeiden, müssen Sie die Inhaberschaft dieser Objekte klar definieren.

Namespace für Typen/Attribute

Neben Label-Konflikten können auch SELinux-Typ- und Attributnamen in Konflikt geraten. SELinux lässt nicht mehrere Deklarationen derselben Typen und Attribute zu. Eine Richtlinie mit doppelten Deklarationen kann nicht kompiliert werden. Um Kollisionen von Typ- und Attributnamen zu vermeiden, wird dringend empfohlen, alle Anbieterdeklarationen mit dem Präfix vendor_ zu beginnen. Verwenden Sie beispielsweise type vendor_foo, domain; anstelle von type foo, domain;.

Dateieigentümerschaft

Kollisionen für Dateien zu verhindern, ist schwierig, da sowohl die Plattform- als auch die Anbieterrichtlinie in der Regel Labels für alle Dateisysteme enthalten. Im Gegensatz zur Typbenennung ist die Namespace-Zuweisung von Dateien nicht praktikabel, da viele von ihnen vom Kernel erstellt werden. Um diese Konflikte zu vermeiden, sollten Sie die Namensrichtlinien für Dateisysteme in diesem Abschnitt beachten. Bei Android 8.0 handelt es sich um Empfehlungen ohne technische Durchsetzung. In Zukunft werden diese Empfehlungen von der Vendor Test Suite (VTS) durchgesetzt.

System (/system)

Nur das Systemimage muss Labels für /system-Komponenten über file_contexts, service_contexts usw. bereitstellen. Wenn Labels für /system-Komponenten in der Anbieterrichtlinie hinzugefügt werden, ist ein reines Framework-OTA-Update möglicherweise nicht möglich.

Anbieter (/vendor)

Die AOSP-SELinux-Richtlinie kennzeichnet bereits Teile der Partition vendor, mit denen die Plattform interagiert. So können SELinux-Regeln für Plattformprozesse geschrieben werden, damit sie mit Teilen der Partition vendor kommunizieren oder darauf zugreifen können. Beispiele:

/vendor path Von der Plattform bereitgestelltes Label Plattformprozesse je nach Label
/vendor(/.*)? vendor_file Alle HAL-Clients im Framework, ueventd usw.
/vendor/framework(/.*)? vendor_framework_file dex2oat, appdomain usw.
/vendor/app(/.*)? vendor_app_file dex2oat, installd, idmap usw.
/vendor/overlay(/.*) vendor_overlay_file system_server, zygote, idmap usw.

Daher müssen beim Labeln zusätzlicher Dateien in der vendor-Partition bestimmte Regeln eingehalten werden (die durch neverallows erzwungen werden):

  • vendor_file muss das Standardlabel für alle Dateien in der Partition vendor sein. Gemäß der Plattformrichtlinie ist dies erforderlich, um auf Passthrough-HAL-Implementierungen zuzugreifen.
  • Alle neuen exec_types, die in der vendor-Partition über die Händlerrichtlinie hinzugefügt werden, müssen das Attribut vendor_file_type haben. Dies wird durch „neverallows“ erzwungen.
  • Um Konflikte mit zukünftigen Plattform-/Framework-Updates zu vermeiden, sollten Sie keine Dateien außer exec_types in der Partition vendor kennzeichnen.
  • Alle Bibliotheksabhängigkeiten für AOSP-identifizierte HALs im selben Prozess müssen als same_process_hal_file. gekennzeichnet sein.

Procfs (/proc)

Dateien in /proc dürfen nur mit dem Label genfscon gekennzeichnet werden. In Android 7.0 wurde in der Plattformrichtlinie und der Anbieterrichtlinie genfscon verwendet, um Dateien in procfs zu kennzeichnen.

Empfehlung:Nur Plattformrichtlinienlabels /proc. Wenn für Anbieterprozesse Zugriff auf Dateien in /proc erforderlich ist, die derzeit mit dem Standardlabel (proc) gekennzeichnet sind, sollten sie in der Anbieterrichtlinie nicht explizit gekennzeichnet werden. Stattdessen sollte der generische Typ proc verwendet werden, um Regeln für Anbieterdomains hinzuzufügen. So können die Plattformupdates zukünftige Kernelschnittstellen berücksichtigen, die über procfs verfügbar gemacht werden, und sie bei Bedarf explizit kennzeichnen.

Debugfs (/sys/kernel/debug)

Debugfs kann sowohl in file_contexts als auch in genfscon gekennzeichnet werden. In Android 7.0 bis Android 10 sind sowohl das Plattform- als auch das Anbieterlabel debugfs.

Unter Android 11 kann auf debugfs auf Produktionsgeräten nicht zugegriffen oder es kann nicht darauf zugegriffen werden. Gerätehersteller sollten debugfs entfernen.

Tracefs (/sys/kernel/debug/tracing)

Tracefs kann sowohl in file_contexts als auch in genfscon gekennzeichnet werden. In Android 7.0 sind nur die Plattformlabels tracefs verfügbar.

Empfehlung:Nur die Plattform darf tracefs kennzeichnen.

Sysfs (/sys)

Dateien in /sys können sowohl mit file_contexts als auch mit genfscon gekennzeichnet werden. In Android 7.0 verwenden sowohl die Plattform als auch der Anbieter genfscon, um Dateien in sysfs zu kennzeichnen.

Empfehlung:Die Plattform kann sysfs-Knoten kennzeichnen, die nicht gerätespezifisch sind. Andernfalls darf nur der Anbieter Dateien kennzeichnen.

tmpfs (/dev)

Dateien in /dev können in file_contexts mit Labels versehen werden. In Android 7.0 werden sowohl die Plattform- als auch die Anbieterlabel-Dateien hier gespeichert.

Empfehlung:Der Anbieter darf nur Dateien in /dev/vendor labeln (z. B. /dev/vendor/foo, /dev/vendor/socket/bar).

Rootfs (/)

Dateien in / können in file_contexts mit Labels versehen werden. In Android 7.0 sind hier sowohl Plattform- als auch Anbieterlabeldateien enthalten.

Empfehlung:Nur das System darf Dateien in / labeln.

Daten (/data)

Die Daten werden durch eine Kombination aus file_contexts und seapp_contexts gekennzeichnet.

Empfehlung:Untersagen Sie die Anbieterkennzeichnung außerhalb von /data/vendor. Nur die Plattform darf andere Teile von /data kennzeichnen.

Genfs Labels-Version

Ab Anbieter‑API‑Level 202504 sind neuere SELinux-Labels, die mit genfscon in system/sepolicy/compat/plat_sepolicy_genfs_ver.cil zugewiesen werden, für ältere vendor-Partitionen optional. So können ältere vendor-Partitionen ihre vorhandene SEPolicy-Implementierung beibehalten. Dies wird durch die Makefile-Variable BOARD_GENFS_LABELS_VERSION gesteuert, die in /vendor/etc/selinux/genfs_labels_version.txt gespeichert ist.

Beispiel:

  • Im Anbieter‑API‑Level 202404 wird der Knoten /sys/class/udc standardmäßig mit sysfs gekennzeichnet.
  • Ab Anbieter‑API‑Level 202504 wird /sys/class/udc mit sysfs_udc gekennzeichnet.

/sys/class/udc wird jedoch möglicherweise von vendor-Partitionen mit API‑Level 202404 verwendet, entweder mit dem Standardlabel sysfs oder einem anbieterspezifischen Label. Wenn /sys/class/udc bedingungslos als sysfs_udc gekennzeichnet wird, kann dies die Kompatibilität mit diesen vendor-Partitionen beeinträchtigen. Wenn Sie BOARD_GENFS_LABELS_VERSION aktivieren, verwendet die Plattform weiterhin die vorherigen Labels und Berechtigungen für die älteren vendor-Partitionen.

BOARD_GENFS_LABELS_VERSION kann größer oder gleich der Vendor API-Ebene sein. Beispielsweise können vendor-Partitionen mit API‑Level 202404 BOARD_GENFS_LABELS_VERSION auf 202504 festlegen, um neue Labels zu übernehmen, die in 202504 eingeführt wurden. Liste der genfs-Labels für 202504

Beim Labeln von genfscon-Knoten muss die Plattform ältere vendor-Partitionen berücksichtigen und bei Bedarf Fallback-Mechanismen für die Kompatibilität implementieren. Die Plattform kann plattformspezifische Bibliotheken verwenden, um die Version der GenFS-Labels abzufragen.

Öffentliche Richtlinie für die Plattform

Die SELinux-Richtlinie der Plattform ist in private und öffentliche Richtlinien unterteilt. Die plattformöffentliche Richtlinie besteht aus Typen und Attributen, die immer für ein Anbieter‑API‑Level verfügbar sind und als API zwischen Plattform und Anbieter fungieren. Diese Richtlinie wird Anbietern zur Verfügung gestellt, damit sie Anbieterrichtliniendateien erstellen können. In Kombination mit der plattformprivaten Richtlinie ergibt sich daraus eine voll funktionsfähige Richtlinie für ein Gerät. Die öffentlich zugängliche Plattformrichtlinie ist in system/sepolicy/public definiert.

Ein Typ vendor_init, der den Initialisierungsprozess im Kontext des Anbieters darstellt, wird beispielsweise unter system/sepolicy/public/vendor_init.te definiert:

type vendor_init, domain;

Anbieter können den Typ vendor_init verwenden, um benutzerdefinierte Richtlinienregeln zu schreiben:

# Allow vendor_init to set vendor_audio_prop in vendor's init scripts
set_prop(vendor_init, vendor_audio_prop)

Kompatibilitätsattribute

Die SELinux-Richtlinie ist eine Interaktion zwischen Quell- und Zieltypen für bestimmte Objektklassen und Berechtigungen. Jedes Objekt (z. B. Prozesse, Dateien), das von der SELinux-Richtlinie betroffen ist, kann nur einen Typ haben, dieser Typ kann jedoch mehrere Attribute haben.

Die Richtlinie ist hauptsächlich in Bezug auf vorhandene Typen formuliert. Hier sind sowohl vendor_init als auch debugfs Typen:

allow vendor_init debugfs:dir { mounton };

Das funktioniert, weil die Richtlinie mit Kenntnis aller Typen geschrieben wurde. Wenn in der Richtlinie des Anbieters und der Plattformrichtlinie jedoch bestimmte Typen verwendet werden und sich das Label eines bestimmten Objekts nur in einer dieser Richtlinien ändert, kann es sein, dass die andere Richtlinie eine Richtlinie enthält, die zuvor auf den Zugriff angewiesen war, der jetzt gewährt oder entzogen wurde. Angenommen, die Plattformrichtlinie kennzeichnet sysfs-Knoten als sysfs:

/sys(/.*)? u:object_r:sysfs:s0

Die Anbieterrichtlinie gewährt Zugriff auf /sys/usb mit dem Label sysfs:

allow vendor_init sysfs:chr_file rw_file_perms;

Wenn die Plattformrichtlinie geändert wird, um /sys/usb als sysfs_usb zu kennzeichnen, bleibt die Anbieterrichtlinie unverändert. vendor_init verliert jedoch den Zugriff auf /sys/usb, da keine Richtlinie für den neuen Typ sysfs_usb vorhanden ist:

/sys/usb u:object_r:sysfs_usb:s0

Um dieses Problem zu beheben, führt Android das Konzept der versionierten Attribute ein. Zur Kompilierzeit übersetzt das Build-System automatisch öffentliche Plattformtypen, die in der Anbieterrichtlinie verwendet werden, in diese versionsbezogenen Attribute. Diese Übersetzung wird durch Zuordnungsdateien ermöglicht, die ein versionsbezogenes Attribut mit einem oder mehreren öffentlichen Typen der Plattform verknüpfen.

Angenommen, /sys/usb ist in der Plattformrichtlinie vom April 2025 als sysfs gekennzeichnet und die Händlerrichtlinie vom April 2025 gewährt vendor_init Zugriff auf /sys/usb. In diesem Fall:

  • In der Anbieterrichtlinie wird die Regel allow vendor_init sysfs:chr_file rw_file_perms; geschrieben, da /sys/usb in der Plattformrichtlinie 202504 als sysfs gekennzeichnet ist. Wenn das Build-System die Anbieterrichtlinie kompiliert, wird die Regel automatisch in allow vendor_init_202504 sysfs_202504:chr_file rw_file_perms; übersetzt. Die Attribute vendor_init_202504 und sysfs_202504 entsprechen den Typen vendor_init und sysfs, die von der Plattform definiert werden.
  • Das Build-System generiert eine Datei für die Identitätszuweisung /system/etc/selinux/mapping/202504.cil. Da sowohl die Partitionen system als auch vendor dieselbe 202504-Version verwenden, enthält die Zuordnungsdatei Identitätszuordnungen von type_202504 zu type. Beispiel: vendor_init_202504 wird vendor_init und sysfs_202504 sysfs zugeordnet:
    (typeattributeset sysfs_202504 (sysfs))
    (typeattributeset vendor_init_202504 (vendor_init))
    ...

Wenn die Version von 202504 auf 202604 aktualisiert wird, wird unter system/sepolicy/private/compat/202504/202504.cil eine neue Zuordnungsdatei für 202504-Partitionenvendor erstellt, die für die 202604- oder neueren system-Partitionen in /system/etc/selinux/mapping/202504.cil installiert wird. Anfangs enthält diese Zuordnungsdatei Identitätszuordnungen, wie oben beschrieben. Wenn der Plattformrichtlinie 202604 ein neues Label sysfs_usb für /sys/usb hinzugefügt wird, wird die Zuordnungsdatei aktualisiert, um sysfs_202504 sysfs_usb zuzuordnen:

(typeattributeset sysfs_202504 (sysfs sysfs_usb))
(typeattributeset vendor_init_202504 (vendor_init))
...

Durch diese Aktualisierung wird der Zugriff auf den neuen Typ sysfs_usb automatisch für die konvertierte Anbieterrichtlinienregel allow vendor_init_202504 sysfs_202504:chr_file rw_file_perms; gewährt.vendor_init

Um die Kompatibilität mit älteren vendor-Partitionen aufrechtzuerhalten, muss jeder neue öffentliche Typ mindestens einem der versionierten Attribute in der Zuordnungsdatei system/sepolicy/private/compat/ver/ver.cil zugeordnet werden oder unter system/sepolicy/private/compat/ver/ver.ignore.cil aufgeführt sein, um anzugeben, dass es in den vorherigen Anbieterversionen keinen passenden Typ gibt.

Durch die Kombination aus Plattformrichtlinie, Anbieterrichtlinie und Zuordnungsdatei kann das System aktualisiert werden, ohne dass die Anbieterrichtlinie aktualisiert werden muss. Die Konvertierung in die versionierten Attribute erfolgt automatisch. Die Anbieterrichtlinie muss sich also nicht um die Versionsverwaltung kümmern, sondern kann die öffentlichen Typen unverändert verwenden.

system_ext-Richtlinie für öffentliche und Produkt-APIs

Ab Android 11 dürfen die Partitionen system_ext und product ihre zugewiesenen öffentlichen Typen in die Partition vendor exportieren. Wie bei der öffentlichen Richtlinie der Plattform werden in der Anbieterrichtlinie Typen und Regeln verwendet, die automatisch in die versionierten Attribute übersetzt werden, z. B. von type in type_ver, wobei ver das Anbieter-API-Level der vendor-Partition ist.

Wenn die Partitionen system_ext und product auf derselben Plattformversion ver basieren, generiert das Build-System Basiszordnungsdateien für system_ext/etc/selinux/mapping/ver.cil und product/etc/selinux/mapping/ver.cil, die Identitätszuordnungen von type zu type_ver enthalten. Die Anbieterrichtlinie kann mit dem Attribut mit Versionsverwaltung type_ver auf type zugreifen.

Wenn nur die Partitionen system_ext und product aktualisiert werden, z. B. von ver auf ver+1 (oder später), während die Partition vendor auf ver bleibt, verliert die Anbieterrichtlinie möglicherweise den Zugriff auf die Typen der Partitionen system_ext und product. Damit keine Fehler auftreten, sollten die Partitionen system_ext und product Zuordnungsdateien von konkreten Typen zu type_ver-Attributen bereitstellen. Jeder Partner ist für die Pflege der Zuordnungsdateien verantwortlich, wenn er die Partitionen ver vendor mit ver+1 (oder höher) system_ext und product unterstützt.

Um Zuordnungsdateien in den Partitionen system_ext und product zu installieren, müssen Gerätehersteller oder ‑anbieter Folgendes tun:

  1. Kopieren Sie die generierten Basiskartierungsdateien aus den Partitionen ver, system_ext und product in den Quellbaum.
  2. Passen Sie die Zuordnungsdateien nach Bedarf an.
  3. Installieren Sie die Zuordnungsdateien auf ver+1 (oder höher) system_ext- und product-Partitionen.

Angenommen, die Partition 202504 system_ext hat einen öffentlichen Typ namens foo_type. Dann sieht system_ext/etc/selinux/mapping/202504.cil in der Partition 202504 system_ext so aus:

(typeattributeset foo_type_202504 (foo_type))
(expandtypeattribute foo_type_202504 true)
(typeattribute foo_type_202504)

Wenn bar_type der Partition 202604 system_ext hinzugefügt wird und bar_type für die Partition 202504 vendor der Partition foo_type zugeordnet werden soll, kann 202504.cil von (typeattributeset foo_type_202504 (foo_type)) zu (typeattributeset foo_type_202504 (foo_type bar_type)) aktualisiert und dann in der Partition 202604 system_ext installiert werden. Die Partition 202504vendor kann weiterhin auf die foo_type und bar_type der Partition 202604system_ext zugreifen.

Attributänderungen für Android 9

Geräte, die auf Android 9 aktualisiert werden, können die folgenden Attribute verwenden. Geräte, die mit Android 9 auf den Markt kommen, dürfen sie jedoch nicht verwenden.

Attribute von Rechtsverletzern

Android 9 umfasst die folgenden domainbezogenen Attribute:

  • data_between_core_and_vendor_violators. Attribute für alle Domains, die gegen die Anforderung verstoßen, Dateien nicht über den Pfad zwischen vendor und coredomains freizugeben. Plattform- und Anbieterprozesse sollten nicht über Dateien auf der Festplatte kommunizieren (instabile ABI). Empfehlung:
    • Der Anbietercode sollte /data/vendor enthalten.
    • Das System sollte /data/vendor nicht verwenden.
  • system_executes_vendor_violators-Attribute für alle Systemdomains (außer init und shell domains), die gegen die Anforderung verstoßen, keine Anbieterbinärdateien auszuführen. Die Ausführung von Anbieter-Binärdateien hat eine instabile API. Die Plattform sollte keine Anbieterbinärdateien direkt ausführen. Empfehlung:
    • Solche Plattformabhängigkeiten von Anbieter-Binärdateien müssen sich hinter HIDL-HALs befinden.

      ODER

    • coredomains, die Zugriff auf Anbieterbinärdateien benötigen, sollten in die Partition vendor verschoben werden und somit nicht mehr coredomain sein.

Nicht vertrauenswürdige Attribute

Nicht vertrauenswürdige Apps, die beliebigen Code hosten, sollten keinen Zugriff auf HwBinder-Dienste haben, mit Ausnahme der Dienste, die als ausreichend sicher für den Zugriff durch solche Apps gelten (siehe unten). Dafür gibt es zwei Hauptgründe:

  1. HwBinder-Server führen keine Clientauthentifizierung durch, da HIDL derzeit keine Informationen zur UID des Aufrufers bereitstellt. Selbst wenn HIDL solche Daten bereitstellen würde, werden viele HwBinder-Dienste entweder auf einer Ebene unter der von Apps (z. B. HALs) ausgeführt oder dürfen sich bei der Autorisierung nicht auf die App-Identität verlassen. Daher wird standardmäßig davon ausgegangen, dass jeder HwBinder-Dienst alle seine Clients als gleichberechtigt für die Ausführung von Vorgängen behandelt, die vom Dienst angeboten werden.
  2. HAL-Server (eine Teilmenge von HwBinder-Diensten) enthalten Code mit einer höheren Häufigkeit von Sicherheitsproblemen als system/core-Komponenten und haben Zugriff auf die unteren Ebenen des Stacks (bis hin zur Hardware). Dadurch steigt die Wahrscheinlichkeit, dass das Android-Sicherheitsmodell umgangen wird.

Sichere Dienste

Zu den sicheren Diensten gehören:

  • same_process_hwservice. Diese Dienste werden (per Definition) im Prozess des Clients ausgeführt und haben daher denselben Zugriff wie die Clientdomain, in der der Prozess ausgeführt wird.
  • coredomain_hwservice. Diese Dienste bergen keine Risiken, die mit Grund 2 verbunden sind.
  • hal_configstore_ISurfaceFlingerConfigs. Dieser Dienst ist speziell für die Verwendung durch jede Domain konzipiert.
  • hal_graphics_allocator_hwservice. Diese Vorgänge werden auch vom surfaceflinger-Bindungsdienst angeboten, auf den Apps zugreifen dürfen.
  • hal_omx_hwservice: Dies ist eine HwBinder-Version des Binder-Dienstes mediacodec, auf den Apps zugreifen dürfen.
  • hal_codec2_hwservice. Dies ist eine neuere Version von hal_omx_hwservice.

Verwendbare Attribute

Alle hwservices, die nicht als sicher gelten, haben das Attribut untrusted_app_visible_hwservice. Die entsprechenden HAL-Server haben das Attribut untrusted_app_visible_halserver. Geräte, die mit Android 9 auf den Markt kommen, DÜRFEN KEINES der untrusted-Attribute verwenden.

Empfehlung:

  • Nicht vertrauenswürdige Apps sollten stattdessen mit einem Systemdienst kommunizieren, der mit dem Vendor-HIDL-HAL kommuniziert. Apps können beispielsweise mit binderservicedomain kommunizieren. mediaserver (eine binderservicedomain) kommuniziert dann mit hal_graphics_allocator.

    ODER

  • Apps, die direkten Zugriff auf vendor-HALs benötigen, sollten eine eigene anbieterspezifische sepolicy-Domain haben.

Tests von Dateiattributen

Android 9 enthält Build-Zeit-Tests, mit denen sichergestellt wird, dass alle Dateien an bestimmten Speicherorten die entsprechenden Attribute haben (z. B. alle Dateien in sysfs das erforderliche Attribut sysfs_type).

SELinux-Kontexte kennzeichnen

Um die Unterscheidung zwischen Plattform- und Anbieter-SELinux-Richtlinien zu unterstützen, erstellt das System SELinux-Kontextdateien auf unterschiedliche Weise, um sie getrennt zu halten.

Dateikontexte

Unter Android 8.0 wurden die folgenden Änderungen für file_contexts eingeführt:

  • Um zusätzlichen Kompilierungsaufwand auf dem Gerät während des Bootvorgangs zu vermeiden, sind file_contexts nicht mehr in binärer Form vorhanden. Stattdessen sind sie lesbare Textdateien mit regulären Ausdrücken wie {property, service}_contexts (wie vor Version 7.0).
  • Die file_contexts sind auf zwei Dateien aufgeteilt:
    • plat_file_contexts
      • Android-Plattform file_context ohne gerätespezifische Labels, mit Ausnahme von Teilen der /vendor-Partition, die genau gekennzeichnet werden müssen, damit die sepolicy-Dateien ordnungsgemäß funktionieren.
      • Muss sich auf dem Gerät in der Partition system unter /system/etc/selinux/plat_file_contexts befinden und zu Beginn zusammen mit dem Anbieter-file_context von init geladen werden.
    • vendor_file_contexts
      • Gerätespezifische file_context, die durch Kombinieren von file_contexts in den Verzeichnissen, auf die von BOARD_SEPOLICY_DIRS in den Boardconfig.mk-Dateien des Geräts verwiesen wird, erstellt werden.
      • Muss unter /vendor/etc/selinux/vendor_file_contexts auf der Partition vendor installiert und zu Beginn zusammen mit der Plattform file_context von init geladen werden.

Property-Kontexte

In Android 8.0 wird property_contexts in zwei Dateien aufgeteilt:

  • plat_property_contexts
    • Android-Plattform property_context ohne gerätespezifische Labels.
    • Muss sich in der Partition system unter /system/etc/selinux/plat_property_contexts befinden und zu Beginn zusammen mit dem Anbieter-property_contexts von init geladen werden.
  • vendor_property_contexts
    • Gerätespezifische property_context, die durch Kombinieren von property_contexts in den Verzeichnissen erstellt werden, auf die von BOARD_SEPOLICY_DIRS in den Boardconfig.mk-Dateien des Geräts verwiesen wird.
    • Muss sich in der Partition vendor unter /vendor/etc/selinux/vendor_property_contexts befinden und zu Beginn zusammen mit der Plattform property_context von init geladen werden.

Dienstkontexte

In Android 8.0 ist die service_contexts auf die folgenden Dateien aufgeteilt:

  • plat_service_contexts
    • Android-plattformspezifische service_context für die servicemanager. Das service_context hat keine gerätespezifischen Labels.
    • Muss sich auf der Partition system unter /system/etc/selinux/plat_service_contexts befinden und zu Beginn zusammen mit dem Anbieter-service_contexts von servicemanager geladen werden.
  • vendor_service_contexts
    • Gerätespezifisches service_context, das durch Kombinieren von service_contexts aus den Verzeichnissen erstellt wird, auf die von BOARD_SEPOLICY_DIRS in den Boardconfig.mk-Dateien des Geräts verwiesen wird.
    • Muss sich in der Partition vendor unter /vendor/etc/selinux/vendor_service_contexts befinden und zu Beginn zusammen mit der Plattform service_contexts von servicemanager geladen werden.
    • servicemanager sucht zwar beim Booten nach dieser Datei, aber für ein vollständig kompatibles TREBLE-Gerät DARF vendor_service_contexts NICHT vorhanden sein. Das liegt daran, dass alle Interaktionen zwischen vendor- und system-Prozessen über hwservicemanager/hwbinder erfolgen MÜSSEN.
  • plat_hwservice_contexts
    • Android-Plattform hwservice_context für hwservicemanager ohne gerätespezifische Labels.
    • Muss sich in der Partition system unter /system/etc/selinux/plat_hwservice_contexts befinden und zu Beginn zusammen mit vendor_hwservice_contexts von hwservicemanager geladen werden.
  • vendor_hwservice_contexts
    • Gerätespezifisches hwservice_context, das durch Kombinieren von hwservice_contexts aus den Verzeichnissen erstellt wird, auf die von BOARD_SEPOLICY_DIRS in den Boardconfig.mk-Dateien des Geräts verwiesen wird.
    • Muss sich in der Partition vendor unter /vendor/etc/selinux/vendor_hwservice_contexts befinden und zu Beginn zusammen mit plat_service_contexts von hwservicemanager geladen werden.
  • vndservice_contexts
    • Gerätespezifische service_context für die vndservicemanager, die durch Kombinieren von vndservice_contexts in den Verzeichnissen, auf die von BOARD_SEPOLICY_DIRS im Boardconfig.mk des Geräts verwiesen wird, erstellt wird.
    • Diese Datei muss sich in der Partition vendor unter /vendor/etc/selinux/vndservice_contexts befinden und zu Beginn von vndservicemanager geladen werden.

Seapp-Kontexte

In Android 8.0 wird seapp_contexts in zwei Dateien aufgeteilt:

  • plat_seapp_contexts
    • Android-Plattform seapp_context ohne gerätespezifische Änderungen.
    • Muss sich in der system-Partition unter /system/etc/selinux/plat_seapp_contexts. befinden.
  • vendor_seapp_contexts
    • Gerätespezifische Erweiterung der Plattform seapp_context, die durch Kombinieren von seapp_contexts in den Verzeichnissen erstellt wird, auf die von BOARD_SEPOLICY_DIRS in den Boardconfig.mk-Dateien des Geräts verwiesen wird.
    • Muss sich in der vendor-Partition unter /vendor/etc/selinux/vendor_seapp_contexts befinden.

MAC-Berechtigungen

In Android 8.0 wird mac_permissions.xml in zwei Dateien aufgeteilt:

  • Plattform mac_permissions.xml
    • Android-Plattform mac_permissions.xml ohne gerätespezifische Änderungen.
    • Muss sich in der system-Partition unter /system/etc/selinux/. befinden.
  • Nicht auf der Plattform mac_permissions.xml
    • Gerätespezifische Erweiterung der Plattform mac_permissions.xml, die aus mac_permissions.xml erstellt wurde und sich in den Verzeichnissen befindet, auf die von BOARD_SEPOLICY_DIRS in den Boardconfig.mk-Dateien des Geräts verwiesen wird.
    • Muss sich in der vendor-Partition unter /vendor/etc/selinux/. befinden.

Änderungen am gemeinsam genutzten Arbeitsspeicher für Android 17

Ab Android 17 müssen Geräte, die mit den folgenden Eigenschaften eingeführt werden, die memfd_class-Richtlinienfunktion aktivieren und ihre Richtlinie für gemeinsam genutzten Speicher so aktualisieren, dass sie memfd_file-Klassenobjekte unterstützt:

  • Anbieter‑API‑Level 202604 oder höher, damit Anbieter und OEMs ihre Anbieterrichtlinie aktualisieren können, um memfd zu unterstützen. Außerdem können vorhandene Geräte auf höhere Android-Versionen aktualisiert werden, ohne dass ihre Anbieterpartition aktualisiert werden muss.
  • android16-6.12 oder höher, da diese Kernel die Funktion memfd_class unterstützen, die für die Implementierung einer detaillierten Richtlinie für memfd erforderlich ist.

„memfd_class“-Richtlinienfunktion aktivieren

Bis vor Kurzem wurde eine memfd von SELinux als Datei mit demselben Typ wie das zugrunde liegende Dateisystem (tmpfs) gekennzeichnet. Aus Richtliniensicht war es daher unmöglich, eine memfd von einer anderen Datei auf einem tmpfs-Mount zu unterscheiden. Jetzt weist SELinux memfd das Sicherheitskontext des zuweisenden Prozesses zu und memfds werden als Objekte der Klasse memfd_file behandelt. Diese Funktion wird durch die memfd_class-Richtlinienfunktion geschützt, um die Abwärtskompatibilität mit älteren Nutzerbereichsumgebungen zu gewährleisten.

Wenn Sie die Richtlinienfunktion memfd_class aktivieren möchten, erstellen Sie eine policy_capabilities-Datei unter BOARD_VENDOR_SEPOLICY_DIRS. Die Datei sollte den folgenden Eintrag enthalten:

# $BOARD_VENDOR_SEPOLICY_DIRS/*/policy_capabilities
policycap memfd_class;

Erstellen Sie dann Ihre Images neu und flashen Sie sie auf Ihr Gerät, um zu prüfen, ob die Funktion aktiviert ist.

Prüfen, ob die Richtlinienfunktion „memfd_class“ aktiviert ist

Verwenden Sie den folgenden Befehl, um den Status der memfd_class-Richtlinienfunktion zu prüfen:

adb shell 'cat /sys/fs/selinux/policy_capabilities/memfd_class'

Wenn das Ergebnis 1 ist, ist die Richtlinienfunktion „memfd_class“ aktiviert. Andernfalls ist sie nicht aktiviert.

Vorhandene Richtlinie auf „memfd“ umstellen

Bei bestimmten Prozessen wurde das tmpfs_domain()-Makro in der Richtlinie verwendet, um auf memfds zuzugreifen und es mit einem Namespace zu versehen, z. B.:

# foo.te
tmpfs_domain(foo)

Das bedeutet:

# foo.te
type_transition foo tmpfs:file foo_tmpfs;
allow foo foo_tmpfs:file { read write getattr map };

und lässt den Zugriffsprozess foo von bar so verarbeiten:memfds

# bar.te
allow bar foo_tmpfs:file { read write getattr map };

Wenn die memfd_class-Richtlinienfunktion aktiviert ist, ist das tmpfs_domain()-Makro nicht mehr erforderlich, da die Plattformrichtlinie aktualisiert wurde. Jetzt kann jeder Prozess ein eigenes memfds erstellen und verwenden.

# system/sepolicy/private/domain.te
allow domain self:memfd_file { create read write getattr map };

und auf memfds, das von Prozess foo erstellt wurde, kann von Prozess bar so zugegriffen werden:

# bar.te
allow bar foo:memfd_file { read write getattr map };

Die Richtlinie der Plattform wurde aktualisiert, um bestehende Verwendungen von memfd zu berücksichtigen. Anbieter- und gerätespezifische Richtlinien, in denen tmpfs-Labels verwendet werden, müssen jedoch auf memfd_file aktualisiert werden. Wenn die Richtlinie für SoCs oder Geräte gilt, die nicht das Anbieter-API-Level 202604 oder höher haben, wird empfohlen, die alte tmpfs-Richtlinie zur Kompatibilität beizubehalten.memfd_file

„memfd“-bezogene AVC-Verweigerungen identifizieren

Memfd-bezogene Ablehnungen können mit dem folgenden Befehl abgerufen werden:

adb shell logcat -d -b events | grep memfd

AVC-Verweigerungen mit „tmpfs“ als Ziel

Das folgende Beispiel zeigt eine avc-Verweigerung, die bei einem Prozess aufgetreten ist, der versucht hat, in eine memfd zu schreiben, für die er keine Schreibberechtigung hatte:

audit(0.0:539): avc:  denied  { write } for  comm="binder:665_1" name="memfd:MessageQueue"
dev="tmpfs" ino=8324 scontext=u:r:mediacodec:s0 tcontext=u:object_r:tmpfs:s0 tclass=file
permissive=0

Wenn die Richtlinienfunktion memfd_class aktiviert ist, ist der Zielkontext eines memfd der Sicherheitskontext des zuweisenden Prozesses, nicht tmpfs, und die Zielklasse ist memfd_file, nicht file. Wenn Sie also avc-Ablehnungen im Zusammenhang mit memfd feststellen, wobei die betreffende memfd als tmpfs-Datei gekennzeichnet ist, ist die memfd_class-Richtlinienfunktion nicht aktiviert.

AVC-Verweigerungen mit „memfd_file“ als Zielklasse

Das folgende Beispiel zeigt eine avc-Ablehnung, die bei einem Prozess aufgetreten ist, der versucht, in eine memfd zu schreiben, für die er keine Schreibberechtigung hatte. Die memfd_class-Richtlinienfunktion war aktiviert. Außerdem wird eine zusätzliche Zeile angezeigt, die von „logd“ nach der Ablehnung mit demselben Zeitstempel ausgegeben wird:

audit(0.0:86): avc: denied { read } for
path=2F6D656D66643A4D6564696142756666657247726F7570202864656C6574656429 ino=512 dev=""
scontext=u:r:mediaserver:s0 tcontext=u:object_r:mediaextractor:s0 tclass=memfd_file

auditd  : Decoded path for audit(0.0:86): /memfd:MediaBufferGroup (deleted)

Der übereinstimmende Zeitstempel weist darauf hin, dass sich die Decoded path for … log auf die Ablehnung mit dem Zeitstempel 0.0.86 bezieht.avc In diesem Log wird der hexadezimale String aus dem Pfadwert in der avc-Ablehnung decodiert und der Name des memfd-Speicherbereichs angegeben. Das kann hilfreich sein, um zu verstehen, welcher Puffer freigegeben wird. Der Quell- und Zielkontext ist hilfreich, um zu verstehen, welche Prozesse Arbeitsspeicher gemeinsam nutzen müssen. Aus dem vorherigen Beispiel geht hervor, dass der mediaserver-Prozess auf die memfds von mediaextractor zugreifen muss. Die entsprechende Richtlinie lautet daher:

# mediaserver.te
allow mediaserver mediaextractor:memfd_file { getattr read write map };

Aktualisierungen der Sicherheitsbereiche in Android 17

Die ASharedMemory_create() API in Android 17 implementiert eine bedingte Logik, um zwischen dem alten ashmem-Treiber und dem memfd-Framework für die Zuweisung von gemeinsam genutztem Speicher auszuwählen.

Bei Geräten, die die memfd-Anforderungen erfüllen (Anbieter-API-Level 202604 oder höher und Kernel android16-6.12 oder höher), wird die targetSdkVersion der aufrufenden App ausgewertet. Wenn die Ziel-SDK-Version 37 oder höher ist, wird ein memfd zugewiesen. So können Entwickler Probleme beheben, die beim Upgrade ihrer Ziel-SDK-Version auftreten.

Wenn das Gerät die memfd's-Voraussetzungen nicht erfüllt, greift ASharedMemory auf ashmem zurück. Dadurch wird die Kompatibilität für aktualisierte Geräte mit älteren Anbieterpartitionen oder ‑kernels aufrechterhalten.

Um diese Umstellung zu erzwingen, blockiert die SELinux-Richtlinie der Plattform Apps, die auf SDK-Version 37 oder höher ausgerichtet sind, in den Sicherheitsbereichen platform_app, priv_app und untrusted_app, wenn sie /dev/ashmem öffnen und ashmem-ioctl-Befehle für memfd aufrufen. Dazu werden diese App-Domains nach Ziel-SDK-Version aufgeteilt. Dadurch werden die Sicherheitsdomains platform_app_36, priv_app_36 und untrusted_app_34 eingeführt, die zusammen mit anderen App-Domains die Berechtigungen zum Öffnen von ashmem und die Möglichkeit zum Aufrufen von ashmem-ioctl-Befehlen für memfds beibehalten.

In einer zukünftigen Android-Version wird die Anzahl der Apps, die Berechtigungen zum Öffnen des ashmem-Geräts und zum Aufrufen von ashmem-ioctl-Befehlen auf memfds behalten, auf platform_app_36, priv_app_36 und untrusted_app_34 sowie nicht vertrauenswürdige App-Domains für ältere SDK-Versionen reduziert.

Benutzerdefinierte SELinux-Richtlinien für Anbieter oder OEMs für Apps, die ihre Ziel-SDK-Version fixieren, müssen entsprechend den in den folgenden Abschnitten beschriebenen Änderungen an den Domains aktualisiert werden.

Aktualisierungen der SELinux-Domain für Plattform-Apps

Die platform_app-Domain wird basierend auf der targetSdkVersion der App aufgeteilt. Plattform-Apps, die auf SDK-Version 37 oder höher ausgerichtet sind, wird die Domain platform_app zugewiesen, während für Apps, die auf SDK-Version 36 oder niedriger ausgerichtet sind, platform_app_36 verwendet wird. Die Domain platform_app_36 kann aus Gründen der Abwärtskompatibilität weiterhin /dev/ashmem öffnen. Verwenden Sie das Attribut platform_app_all, um die Richtlinienverwaltung für beide Domains zu vereinfachen.

Nehmen wir an, die Plattform-App sample-plat-app muss Daten aus /dev/foo_device lesen und in /dev/foo_device schreiben. Die vorhandene SELinux-Richtlinie des Anbieters könnte so aussehen:

# This will only allow sample-plat-app to access the device if it
# is placed in the platform_app domain (i.e. target SDK version is 37 or higher).
allow platform_app foo_device:chr_file rw_file_perms;

Wenn sample-plat-app jedoch an die Ziel-SDK-Version 36 angepinnt ist, wird sie in der platform_app_36-Domain platziert. Die SELinux-Richtlinie von früher gilt dann nicht und der folgende AVC-Fehler wird beobachtet:

auditd  : type=1400 audit(0.0:11): avc:  denied  { read write } for  comm="sample-plat-app" path="/dev/foo_device" dev="tmpfs" ino=1609 scontext=u:r:platform_app_36:s0:c512,c768 tcontext=u:object_r:foo_device:s0 tclass=chr_file permissive=0

Um das Problem zu beheben, kann die Richtlinie so aktualisiert werden, da die App immer Zugriff auf den Geräteknoten haben sollte:

# This allows sample-plat-app to access the device independent of
# target SDK version.
allow platform_app_all foo_device:chr_file rw_file_perms;

Es kann Situationen geben, in denen platform_app_all nicht funktioniert. Wenn das Makro hal_client_domain() beispielsweise mit platform_app_all verwendet wird, kann die Richtlinie nicht kompiliert werden. Das liegt daran, dass platform_app_all ein Attribut ist und hal_client_domain() versucht, ein weiteres Attribut daran anzuhängen, was nicht möglich ist:

# platform_app.te
hal_client_domain(platform_app, hal_foo)

In diesen Fällen muss der Typ platform_app_36 direkt verwendet werden, sodass Ihre Richtlinie die folgenden Inhalte hat:

# platform_app.te
hal_client_domain(platform_app, hal_foo)

# platform_app_36.te
hal_client_domain(platform_app_36, hal_foo)

Aktualisierungen der SELinux-Domain für Apps mit privilegierten Berechtigungen

Die priv_app-Domain wird basierend auf der targetSdkVersion der App aufgeteilt. Privilegierte Apps, die auf SDK-Version 37 oder höher ausgerichtet sind, werden der Domain priv_app zugewiesen, während Apps, die auf SDK-Version 36 oder niedriger ausgerichtet sind, priv_app_36 verwenden. Die Domain priv_app_36 kann aus Gründen der Abwärtskompatibilität weiterhin /dev/ashmem öffnen. Verwenden Sie das Attribut priv_app_all, um die Richtlinienverwaltung für beide Domains zu vereinfachen.

Nehmen wir an, die Plattform-App sample-priv-app muss Daten aus /dev/foo_device lesen und in /dev/foo_device schreiben. Die vorhandene SELinux-Richtlinie des Anbieters könnte so aussehen:

# This will only allow sample-priv-app to access the device if it
# is placed in the priv_app domain (i.e. target SDK version is 37 or higher).
allow priv_app foo_device:chr_file rw_file_perms;

Wenn sample-priv-app jedoch an die Ziel-SDK-Version 36 angepinnt ist, wird sie in der priv_app_36-Domain platziert. Die SELinux-Richtlinie von früher gilt dann nicht und der folgende AVC-Fehler wird beobachtet:

auditd  : type=1400 audit(0.0:11): avc:  denied  { read write } for  comm="sample-priv-app" path="/dev/foo_device" dev="tmpfs" ino=1609 scontext=u:r:priv_app_36:s0:c512,c768 tcontext=u:object_r:foo_device:s0 tclass=chr_file permissive=0

Um das Problem zu beheben, kann die Richtlinie so aktualisiert werden, da die App immer Zugriff auf den Geräteknoten haben sollte:

# This allows sample-priv-app to access the device independent of
# target SDK version.
allow priv_app_all foo_device:chr_file rw_file_perms;

Es kann Situationen geben, in denen priv_app_all nicht funktioniert. Wenn das Makro hal_client_domain() beispielsweise mit priv_app_all verwendet wird, kann die Richtlinie nicht kompiliert werden. Das liegt daran, dass priv_app_all ein Attribut ist und hal_client_domain() versucht, ein weiteres Attribut daran anzuhängen, was nicht möglich ist:

# priv_app.te
hal_client_domain(priv_app, hal_foo)

In diesen Fällen muss der Typ priv_app_36 direkt verwendet werden. Ihre Richtliniendateien sehen dann so aus:

# priv_app.te
hal_client_domain(priv_app, hal_foo)

# priv_app_36.te
hal_client_domain(priv_app_36, hal_foo)

Aktualisierungen der SELinux-Domain „untrusted_app“

Die untrusted_app-Domain wird basierend auf der targetSdkVersion der App aufgeteilt. Nicht vertrauenswürdige Apps, die auf SDK-Version 37 oder höher ausgerichtet sind, werden der Domain untrusted_app zugewiesen, während Apps, die auf SDK-Versionen 34 bis 36 ausgerichtet sind, der neuen Domain untrusted_app_34 zugewiesen werden. In der untrusted_app_34-Domain sowie in den untrusted_app_X-Domains, wobei „X“ eine ältere Target-SDK-Version ist, kann `/dev/ashmem` aus Gründen der Abwärtskompatibilität weiterhin geöffnet werden.