In diesem Artikel wird beschrieben, wie Android mit Richtlinienkompatibilitätsproblemen bei Plattform-OTAs umgeht, bei denen sich die neuen SELinux-Einstellungen der Plattform von den alten SELinux-Einstellungen des Anbieters unterscheiden können.
Bei der Treble-basierten SELinux-Richtlinienentwicklung wird zwischen Plattform- und Anbieterrichtlinien unterschieden. Das System wird komplizierter, wenn Anbieterpartitionen Abhängigkeiten erzeugen, z. B. platform
< vendor
< oem
.
In Android 8.0 und höher ist die globale SELinux-Richtlinie in private und öffentliche Komponenten unterteilt. Öffentliche Komponenten bestehen aus der Richtlinie und der zugehörigen Infrastruktur, die für eine Plattformversion garantiert verfügbar sind. Diese Richtlinie wird Anbietern zur Verfügung gestellt, damit sie eine Anbieterrichtliniendatei erstellen können, die in Kombination mit der von der Plattform bereitgestellten Richtlinie eine voll funktionsfähige Richtlinie für ein Gerät ergibt.
- Für die Versionierung werden die exportierten öffentlichen Plattformrichtlinien als Attribute geschrieben.
- Für die leichtere Erstellung von Richtlinien werden exportierte Typen im Rahmen des Richtlinienerstellungsprozesses in versionierte Attribute umgewandelt. Öffentliche Typen können auch direkt in Entscheidungen zur Kennzeichnung verwendet werden, die in Dateien mit Anbieterkontexten enthalten sind.
Android pflegt eine Zuordnung zwischen den exportierten konkreten Typen in der Plattformrichtlinie und den entsprechenden versionierten Attributen für jede Plattformversion. So wird sichergestellt, dass das Verhalten von Objekten, die mit einem Typ gekennzeichnet sind, nicht gegen die in einer früheren Version der Plattform-Richtlinien für die Öffentlichkeit garantierten Verhaltensweisen verstößt. Diese Zuordnung wird durch eine Zuordnungsdatei für jede Plattformversion aufrechterhalten, in der Informationen zur Attributmitgliedschaft für jeden Typ gespeichert werden, der in den öffentlichen Richtlinien exportiert wird.
Eigentumsrechte an Objekten und Labeling
Wenn Sie die Richtlinie unter Android 8.0 und höher anpassen, muss die Inhaberschaft für jedes Objekt klar definiert sein, damit Plattform- und Anbieterrichtlinien getrennt bleiben. Wenn der Anbieter beispielsweise /dev/foo
und die Plattform dann /dev/foo
in einer nachfolgenden OTA-Transaktion kennzeichnet, ist das Verhalten nicht definiert. Bei SELinux führt dies zu einer Labelkonflikt. Der Geräteknoten kann nur ein einzelnes Label haben, das auf das zuletzt angewendete Label verweist. Daraus ergeben sich folgende Konsequenzen:
- Prozesse, die Zugriff auf das erfolglos angewendete Label benötigen, verlieren den Zugriff auf die Ressource.
- Prozesse, die Zugriff auf die Datei erhalten, können fehlerhaft laufen, weil der falsche Geräteknoten erstellt wurde.
Systemeigenschaften können auch zu Namenskollisionen führen, die zu undefiniertem Verhalten des Systems (sowie zu SELinux-Labeln) führen können. Kollisionen zwischen Plattform- und Anbieterlabels können bei allen Objekten mit einem SELinux-Label auftreten, einschließlich Properties, Diensten, Prozessen, Dateien und Sockets. Um diese Probleme zu vermeiden, sollten Sie die Eigentumsrechte an diesen Objekten klar definieren.
Neben Labelkollisionen können auch SELinux-Typ-/Attributnamen kollidieren. Ein Konflikt zwischen dem Namen eines Typs und dem Namen eines Attributs führt immer zu einem Richtlinien-Compilerfehler.
Namespace für Typ/Attribut
SELinux erlaubt keine Mehrfachdeklarationen desselben Typs/Attributs. Richtlinien mit doppelten Deklarationen können nicht kompiliert werden. Um Namenskollisionen bei Typen und Attributen zu vermeiden, sollten alle Anbieterdeklarationen mit vendor_
beginnen.
type foo, domain; → type vendor_foo, domain;
Eigentumsrechte an Systemeigenschaften und Prozesslabeln
Kollisionen bei Labels lassen sich am besten mithilfe von Property-Namespaces vermeiden. Damit Sie Plattformeigenschaften leicht identifizieren und Namenskonflikte beim Umbenennen oder Hinzufügen von exportierten Plattformeigenschaften vermeiden können, sollten alle Anbietereigenschaften eigene Präfixe haben:
Property-Typ | Zulässige Präfixe |
---|---|
Steuerelementeigenschaften | ctl.vendor. ctl.start$vendor. ctl.stop$vendor. init.svc.vendor.
|
Lese-/Schreibzugriff | vendor. |
schreibgeschützt | ro.vendor. ro.boot. ro.hardware.
|
persistent | persist.vendor. |
Anbieter können weiterhin ro.boot.*
(aus der Kernel-cmdline) und ro.hardware.*
(eine offensichtlich hardwarebezogene Eigenschaft) verwenden.
Alle Anbieterdienste in init-rc-Dateien sollten vendor.
für Dienste in init-rc-Dateien von nicht systemeigenen Partitionen haben. Ähnliche Regeln gelten für die SELinux-Labels für die Anbietereigenschaften (vendor_
für die Anbietereigenschaften).
Dateieigentümer
Kollisionen bei Dateien zu verhindern, ist schwierig, da sowohl Plattform- als auch Anbieterrichtlinien in der Regel Labels für alle Dateisysteme bereitstellen. Im Gegensatz zur Benennung von Typen ist die Benennung von Dateien im Namespace nicht praktikabel, da viele von ihnen vom Kernel erstellt werden. Folgen Sie der Anleitung in diesem Abschnitt, um diese Kollisionen zu vermeiden. Bei Android 8.0 handelt es sich dabei um Empfehlungen ohne technische Erzwingung. Künftig werden diese Empfehlungen durch die Vendor Test Suite (VTS) erzwungen.
System (/system)
Nur das Systemimage muss Labels für /system
-Komponenten (file_contexts
, service_contexts
usw.) bereitstellen. Wenn Labels für /system
-Komponenten in der /vendor
-Richtlinie hinzugefügt werden, ist ein OTA-Update nur für das Framework möglicherweise nicht möglich.
Anbieter (/vendor)
Die AOSP-SELinux-Richtlinie kennzeichnet bereits Teile der vendor
-Partition, mit denen die Plattform interagiert. Dadurch können SELinux-Regeln für Plattformprozesse geschrieben werden, damit sie mit Teilen der vendor
-Partition kommunizieren und/oder darauf zugreifen können. Beispiele:
Pfad zu /vendor |
Von der Plattform bereitgestelltes Label | Plattformprozesse, die vom Label abhängen |
---|---|---|
/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 Beschriften zusätzlicher Dateien in der vendor
-Partition bestimmte Regeln befolgt werden, die über neverallows
erzwungen werden:
vendor_file
muss das Standardlabel für alle Dateien in dervendor
-Partition sein. Laut der Plattformrichtlinie ist dies für den Zugriff auf Passthrough-HAL-Implementierungen erforderlich.- Alle neuen
exec_types
, die über die SEPolicy des Anbieters dervendor
-Partition hinzugefügt werden, müssen das Attributvendor_file_type
haben. Dies wird durch „neverallows“ erzwungen. - Um Konflikte mit zukünftigen Plattform-/Framework-Updates zu vermeiden, sollten Sie in der Partition
vendor
keine anderen Dateien alsexec_types
kennzeichnen. - Alle Bibliotheksabhängigkeiten für von AOSP identifizierte HALs für denselben 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 sowohl in der Plattform als auch in der Anbieterrichtlinie genfscon
zum Beschriften von Dateien in procfs
verwendet.
Empfehlung:Nur Labels für Plattformrichtlinien /proc
Wenn vendor
-Prozesse Zugriff auf Dateien in /proc
benötigen, 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 Kernel-Schnittstellen berücksichtigen, die über procfs
freigegeben werden, und sie bei Bedarf explizit kennzeichnen.
Debugfs (/sys/kernel/debug)
Debugfs
kann sowohl in file_contexts
als auch in genfscon
beschriftet werden. Unter Android 7.0 bis Android 10 werden sowohl das Plattform- als auch das Anbieterlabel verwendet.
debugfs
Unter Android 11 kann auf debugfs
nicht zugegriffen oder es kann nicht auf Produktionsgeräten bereitgestellt werden. Gerätehersteller sollten debugfs
entfernen.
Tracefs (/sys/kernel/debug/tracing)
Tracefs
kann sowohl in file_contexts
als auch in genfscon
beschriftet werden. Unter Android 7.0 werden nur die Plattformlabels angezeigt.tracefs
Empfehlung:Nur die Plattform darf tracefs
kennzeichnen.
Sysfs (/sys)
Dateien in /sys
können sowohl mit file_contexts
als auch mit genfscon
gekennzeichnet werden. Unter Android 7.0 verwenden sowohl die Plattform als auch der Anbieter genfscon
, um Dateien in sysfs
zu labeln.
Empfehlung:Die Plattform kann sysfs
-Knoten kennzeichnen, die nicht gerätespezifisch sind. Andernfalls kann nur der Anbieter Dateien labeln.
tmpfs (/dev)
Dateien in /dev
können in file_contexts
gekennzeichnet werden. Unter Android 7.0 sind hier sowohl Plattform- als auch Anbieterlabeldateien verfügbar.
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
gekennzeichnet werden. Unter Android 7.0 finden Sie hier sowohl Plattform- als auch Anbieterlabeldateien.
Empfehlung:Dateien in /
dürfen nur vom System getaggt werden.
Daten (/data)
Daten werden durch eine Kombination aus file_contexts
und seapp_contexts
gekennzeichnet.
Empfehlung:Legen Sie fest, dass Anbieterlabels außerhalb von /data/vendor
nicht zulässig sind. Nur die Plattform darf andere Teile von /data
kennzeichnen.
Version der Genfs-Labels
Ab dem API-Level des Anbieters 202504 sind neuere SELinux-Labels, die mit genfscon
in system/sepolicy/compat/plat_sepolicy_genfs_{ver}.cil
zugewiesen sind, für ältere Anbieterpartitionen optional. So können ältere Anbieterpartitionen 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:
-
In der API-Ebene des Anbieters 202404 ist der Knoten
/sys/class/udc
standardmäßig mitsysfs
gekennzeichnet. -
Ab der Anbieter-API-Ebene 202504 wird
/sys/class/udc
alssysfs_udc
gekennzeichnet.
/sys/class/udc
wird jedoch möglicherweise von Anbieterpartitionen mit API-Ebene 202404 verwendet, entweder mit dem Standardlabel sysfs
oder einem anbieterspezifischen Label. Wenn /sys/class/udc
bedingungslos als sysfs_udc
gekennzeichnet wird, kann die Kompatibilität mit diesen Partitionen des Anbieters beeinträchtigt werden. Wenn Sie BOARD_GENFS_LABELS_VERSION
aktivieren, verwendet die Plattform weiterhin die vorherigen Labels und Berechtigungen für die älteren Anbieterpartitionen.
BOARD_GENFS_LABELS_VERSION
kann größer oder gleich der Anbieter-API-Ebene sein. Anbieterpartitionen, die API-Level 202404 verwenden, können BOARD_GENFS_LABELS_VERSION
beispielsweise auf 202504 festlegen, um neue Labels zu übernehmen, die 202504 eingeführt wurden. Liste der
202504-spezifischen genfs-Labels
Beim Beschriften von genfscon
-Knoten muss die Plattform ältere Anbieterpartitionen berücksichtigen und bei Bedarf Fallback-Mechanismen für die Kompatibilität implementieren. Die Plattform kann nur für die Plattform bestimmte Bibliotheken verwenden, um die Genfs-Labels-Version abzufragen.
-
Verwenden Sie für native Inhalte
libgenfslabelsversion
. Die Headerdatei vonlibgenfslabelsversion
finden Sie untergenfslabelsversion.h
. -
Verwenden Sie unter Java
android.os.SELinux.getGenfsLabelsVersion()
.
Kompatibilitätsattribute
Eine SELinux-Richtlinie ist eine Interaktion zwischen Quell- und Zieltypen für bestimmte Objektklassen und Berechtigungen. Jedes Objekt (Prozesse, Dateien usw.), das von der SELinux-Richtlinie betroffen ist, kann nur einen Typ haben, dieser Typ kann jedoch mehrere Attribute haben.
Die Richtlinie bezieht sich hauptsächlich auf vorhandene Typen:
allow source_type target_type:target_class permission(s);
Das funktioniert, weil die Richtlinie mit dem Wissen um alle Arten verfasst wurde. Wenn jedoch in der Anbieterrichtlinie und der Plattformrichtlinie bestimmte Typen verwendet werden und sich das Label eines bestimmten Objekts nur in einer dieser Richtlinien ändert, kann die andere Richtlinie Zugriff gewähren oder entziehen, auf den zuvor vertraut wurde. Beispiel:
File_contexts: /sys/A u:object_r:sysfs:s0 Platform: allow p_domain sysfs:class perm; Vendor: allow v_domain sysfs:class perm;
Könnte zu Folgendem geändert werden:
File_contexts: /sys/A u:object_r:sysfs_A:s0
Die Richtlinie des Anbieters bleibt gleich, aber der v_domain
verliert den Zugriff, da es keine Richtlinie für den neuen sysfs_A
-Typ gibt.
Wenn wir eine Richtlinie in Form von Attributen definieren, können wir dem zugrunde liegenden Objekt einen Typ zuweisen, der ein Attribut mit einer Richtlinie für den Plattform- und Anbietercode hat. Das kann für alle Typen erfolgen, um eine Attributrichtlinie zu erstellen, in der keine konkreten Typen verwendet werden. In der Praxis ist dies nur für die Teile der Richtlinie erforderlich, die sich zwischen Plattform und Anbieter überschneiden. Diese werden als öffentliche Plattformrichtlinie definiert und als Teil der Anbieterrichtlinie bereitgestellt.
Wenn Sie öffentliche Richtlinien als versionierte Attribute definieren, werden zwei Ziele der Richtlinienkompatibilität erfüllt:
- Achten Sie darauf, dass der Anbietercode nach der Plattformaktualisierung weiterhin funktioniert. Dazu werden Attribute zu bestimmten Typen für Objekte hinzugefügt, die denen entsprechen, auf die sich der Anbietercode stützte, um den Zugriff zu erhalten.
- Möglichkeit, Richtlinien einzustellen Dies wird erreicht, indem Richtliniensätze klar in Attribute unterteilt werden, die entfernt werden können, sobald die Version, der sie entsprechen, nicht mehr unterstützt wird. Die Entwicklung kann auf der Plattform fortgesetzt werden, da die alte Richtlinie weiterhin in der Anbieterrichtlinie vorhanden ist und bei einem Upgrade automatisch entfernt wird.
Schreibbarkeit von Richtlinien
Damit für die Richtlinienentwicklung keine Kenntnisse zu bestimmten Versionsänderungen erforderlich sind, enthält Android 8.0 eine Zuordnung zwischen plattformöffentlichen Richtlinientypen und ihren Attributen. Der Typ foo
ist dem Attribut foo_vN
zugeordnet. N
ist die Version, auf die die Ausrichtung erfolgt. vN
entspricht der Buildvariablen PLATFORM_SEPOLICY_VERSION
und hat das Format MM.NN
, wobei MM
der SDK-Nummer der Plattform entspricht und NN
eine plattformspezifische Sepolicy-Version ist.
Attribute in öffentlichen Richtlinien sind nicht versioniert, sondern existieren als API, auf der Plattform- und Anbieterrichtlinien aufgebaut werden können, um die Schnittstelle zwischen den beiden Partitionen stabil zu halten. Sowohl Plattform- als auch Anbieterrichtlinien können weiterhin wie bisher verfasst werden.
Die als allow source_foo target_bar:class
perm;
exportierte Plattform-Richtlinie ist Teil der Anbieterrichtlinie. Während der Kompilierung (einschließlich der entsprechenden Version) wird sie in die Richtlinie umgewandelt, die an den Anbieterbereich des Geräts gesendet wird (in der umgewandelten Common Intermediate Language (CIL) dargestellt):
(allow source_foo_vN target_bar_vN (class (perm)))
Da die Richtlinien der Anbieter nie der Plattform voraus sind, sollten sie sich nicht auf frühere Versionen beziehen. Die Plattformrichtlinie muss jedoch wissen, wie alt die Anbieterrichtlinie ist, Attribute zu den Typen einschließen und eine Richtlinie für die versionierten Attribute festlegen.
Richtlinienabweichungen
Wenn Sie Attribute automatisch erstellen, indem Sie am Ende jedes Typs _vN
hinzufügen, passiert ohne Zuordnung von Attributen zu Typen über Versionsunterschiede hinweg nichts. Android unterstützt eine Zuordnung zwischen Versionen für Attribute und eine Zuordnung von Typen zu diesen Attributen. Dies geschieht in den oben genannten Zuordnungsdateien mit Anweisungen wie (CIL):
(typeattributeset foo_vN (foo))
Plattformupdates
Im folgenden Abschnitt werden Szenarien für Plattformupgrades beschrieben.
Gleiche Typen
Dieses Szenario tritt auf, wenn für ein Objekt keine Labels in Richtlinienversionen geändert werden.
Das gilt für Quell- und Zieltypen gleichermaßen und kann anhand von /dev/binder
veranschaulicht werden, das in allen Releases mit binder_device
gekennzeichnet ist. In der umgewandelten Richtlinie wird sie so dargestellt:
binder_device_v1 … binder_device_vN
Beim Upgrade von v1
auf v2
muss die Plattformrichtlinie Folgendes enthalten:
type binder_device; -> (type binder_device) (in CIL)
In der V1-Zuordnungsdatei (CIL):
(typeattributeset binder_device_v1 (binder_device))
In der V2-Zuordnungsdatei (CIL):
(typeattributeset binder_device_v2 (binder_device))
In der Anbieterrichtlinie der Version 1 (CIL):
(typeattribute binder_device_v1) (allow binder_device_v1 …)
In der Anbieterrichtlinie der Version 2 (CIL):
(typeattribute binder_device_v2) (allow binder_device_v2 …)
Neue Typen
Dieses Szenario tritt auf, wenn der Plattform ein neuer Typ hinzugefügt wurde. Das kann beim Hinzufügen neuer Funktionen oder bei der Richtlinienverschärfung passieren.
- Neue Funktion Wenn der Typ ein Objekt kennzeichnet, das zuvor nicht vorhanden war (z. B. einen neuen Dienstprozess), hat der Anbietercode zuvor nicht direkt mit ihm interagiert. Daher gibt es keine entsprechende Richtlinie. Das neue Attribut, das dem Typ entspricht, hat in der vorherigen Version kein Attribut. Daher ist kein Eintrag in der Zuordnungsdatei für diese Version erforderlich.
- Richtlinienhärtung Wenn der Typ eine Richtlinienverschärfung darstellt, muss das neue Typattribut auf eine Kette von Attributen verweisen, die der vorherigen entsprechen (ähnlich wie im vorherigen Beispiel, in dem
/sys/A
vonsysfs
insysfs_A
geändert wird). Der Anbietercode basiert auf einer Regel, die den Zugriff aufsysfs
ermöglicht, und muss diese Regel als Attribut des neuen Typs enthalten.
Beim Upgrade von v1
auf v2
muss die Plattformrichtlinie Folgendes enthalten:
type sysfs_A; -> (type sysfs_A) (in CIL) type sysfs; (type sysfs) (in CIL)
In der V1-Zuordnungsdatei (CIL):
(typeattributeset sysfs_v1 (sysfs sysfs_A))
In der V2-Zuordnungsdatei (CIL):
(typeattributeset sysfs_v2 (sysfs)) (typeattributeset sysfs_A_v2 (sysfs_A))
In der Anbieterrichtlinie der Version 1 (CIL):
(typeattribute sysfs_v1) (allow … sysfs_v1 …)
In der Anbieterrichtlinie der Version 2 (CIL):
(typeattribute sysfs_A_v2) (allow … sysfs_A_v2 …) (typeattribute sysfs_v2) (allow … sysfs_v2 …)
Entfernte Typen
Dieses (seltene) Szenario tritt auf, wenn ein Typ entfernt wird. Das kann passieren, wenn das zugrunde liegende Objekt:
- Bleibt erhalten, erhält aber ein anderes Label.
- von der Plattform entfernt wird.
Bei der Lockerung einer Richtlinie wird ein Typ entfernt und dem mit diesem Typ gekennzeichneten Objekt wird ein anderes, bereits vorhandenes Label zugewiesen. Dies entspricht einer Zusammenführung von Attributzuordnungen: Der Anbietercode muss weiterhin über das Attribut, das er zuvor hatte, auf das zugrunde liegende Objekt zugreifen können. Der Rest des Systems muss jetzt jedoch über das neue Attribut darauf zugreifen können.
Wenn das Attribut, zu dem gewechselt wurde, neu ist, erfolgt das Umbenennen wie beim neuen Typ. Wenn jedoch ein vorhandenes Label verwendet wird, würde das Hinzufügen des alten Attributtyps dazu führen, dass andere Objekte, die ebenfalls mit diesem Typ gekennzeichnet sind, neu zugänglich werden. Das ist im Wesentlichen das, was die Plattform tut, und wird als akzeptabler Kompromiss zur Aufrechterhaltung der Kompatibilität angesehen.
(typeattribute sysfs_v1) (allow … sysfs_v1 …)
Beispiel Version 1: Zusammenklappbare Typen (Entfernen von sysfs_A)
Beim Upgrade von v1
auf v2
muss die Plattformrichtlinie Folgendes enthalten:
type sysfs; (type sysfs) (in CIL)
In der V1-Zuordnungsdatei (CIL):
(typeattributeset sysfs_v1 (sysfs)) (type sysfs_A) # in case vendors used the sysfs_A label on objects (typeattributeset sysfs_A_v1 (sysfs sysfs_A))
In der V2-Zuordnungsdatei (CIL):
(typeattributeset sysfs_v2 (sysfs))
In der Anbieterrichtlinie der Version 1 (CIL):
(typeattribute sysfs_A_v1) (allow … sysfs_A_v1 …) (typeattribute sysfs_v1) (allow … sysfs_v1 …)
In der Anbieterrichtlinie der Version 2 (CIL):
(typeattribute sysfs_v2) (allow … sysfs_v2 …)
Beispielversion 2: Vollständiges Entfernen (Typ „foo“)
Beim Upgrade von v1
auf v2
muss die Plattformrichtlinie Folgendes enthalten:
# nothing - we got rid of the type
In der V1-Zuordnungsdatei (CIL):
(type foo) #needed in case vendors used the foo label on objects (typeattributeset foo_v1 (foo))
In der V2-Zuordnungsdatei (CIL):
# nothing - get rid of it
In der Anbieterrichtlinie der Version 1 (CIL):
(typeattribute foo_v1) (allow foo …) (typeattribute sysfs_v1) (allow sysfs_v1 …)
In der Anbieterrichtlinie der Version 2 (CIL):
(typeattribute sysfs_v2) (allow sysfs_v2 …)
Neue Kurse/Berechtigungen
Dieses Szenario tritt auf, wenn durch ein Plattformupdate neue Richtlinienkomponenten eingeführt werden, die in früheren Versionen nicht vorhanden sind. Als Android beispielsweise den servicemanager
-Objektmanager hinzufügte, der die Berechtigungen „Hinzufügen“, „Suchen“ und „Auflisten“ erstellte, benötigten Anbieter-Dämonen, die sich beim servicemanager
registrieren wollten, Berechtigungen, die nicht verfügbar waren. Unter Android 8.0 können nur in der Plattformrichtlinie neue Klassen und Berechtigungen hinzugefügt werden.
Damit alle Domains, die gemäß der Anbieterrichtlinie erstellt oder erweitert werden konnten, die neue Klasse ohne Einschränkungen verwenden können, muss die Plattformrichtlinie eine Regel wie die folgende enthalten:
allow {domain -coredomain} *:new_class perm;
Möglicherweise ist sogar eine Richtlinie erforderlich, die den Zugriff für alle Arten von Oberflächen (öffentliche Richtlinie) zulässt, damit das Anbieterbild Zugriff erhält. Wenn dies zu einer nicht akzeptablen Sicherheitsrichtlinie führt (wie es bei den Änderungen am Dienstmanager der Fall sein könnte), kann ein Anbieterupgrade erzwungen werden.
Entfernte Klasse/Berechtigungen
Dieses Szenario tritt auf, wenn ein Objektmanager entfernt wird, z. B. der ZygoteConnection
-Objektmanager. Es sollte keine Probleme verursachen. Die Objektmanager-Klasse und die Berechtigungen können in der Richtlinie so lange definiert bleiben, bis sie in der Anbieterversion nicht mehr verwendet werden. Dazu fügen Sie die Definitionen der entsprechenden Zuordnungsdatei hinzu.
Anbieteranpassung für neue/umbenannte Typen
Neue Anbietertypen stehen im Mittelpunkt der Entwicklung von Anbieterrichtlinien, da sie zur Beschreibung neuer Prozesse, Binärdateien, Geräte, Subsysteme und gespeicherter Daten erforderlich sind. Daher ist es unerlässlich, das Erstellen von vom Anbieter definierten Typen zuzulassen.
Da die Richtlinien des Anbieters immer die ältesten auf dem Gerät sind, müssen nicht alle Anbietertypen automatisch in Attribute in der Richtlinie umgewandelt werden. Die Plattform verwendet keine in den Richtlinien des Anbieters gekennzeichneten Elemente, da sie diese nicht kennt. Sie stellt jedoch die Attribute und öffentlichen Typen bereit, die sie zur Interaktion mit Objekten verwendet, die mit diesen Typen gekennzeichnet sind (z. B. domain
, sysfs_type
usw.). Damit die Plattform weiterhin richtig mit diesen Objekten interagieren kann, müssen die Attribute und Typen richtig angewendet werden. Möglicherweise müssen den anpassbaren Domains (z. B. init
) auch bestimmte Regeln hinzugefügt werden.
Attributänderungen für Android 9
Die folgenden Attribute können auf Geräten verwendet werden, die auf Android 9 umgestellt werden. Auf Geräten, die mit Android 9 ausgeliefert werden, sind sie jedoch nicht zulässig.
Attribute für Richtlinienverstöße
Android 9 umfasst die folgenden domainbezogenen Attribute:
data_between_core_and_vendor_violators
: Attribut für alle Domains, die gegen die Anforderung verstoßen, Dateien nicht über den Pfad zwischenvendor
undcoredomains
freizugeben. Plattform- und Anbieterprozesse sollten keine Dateien auf dem Laufwerk zur Kommunikation verwenden (instabiles ABI). Empfehlung:- Für den Anbietercode sollte
/data/vendor
verwendet werden. - Das System sollte
/data/vendor
nicht verwenden.
- Für den Anbietercode sollte
system_executes_vendor_violators
: Attribut für alle Systemdomains (außerinit
undshell domains
), die gegen die Anforderung verstoßen, keine Binärdateien von Anbietern auszuführen. Die Ausführung von Anbieter-Binärdateien hat eine instabile API. Die Plattform darf Anbieter-Binärdateien nicht direkt ausführen. Empfehlung:- Solche Plattformabhängigkeiten von Anbieterbinärdateien müssen hinter HIDL HALs liegen.
ODER
coredomains
, die Zugriff auf Anbieterbinärdateien benötigen, sollten in die Anbieterpartition verschoben werden und sind dann keinecoredomain
mehr.
- Solche Plattformabhängigkeiten von Anbieterbinärdateien müssen hinter HIDL HALs liegen.
Nicht vertrauenswürdige Attribute
Nicht vertrauenswürdige Apps, die beliebigen Code hosten, sollten keinen Zugriff auf HwBinder-Dienste haben, mit Ausnahme derjenigen, die für den Zugriff durch solche Apps als ausreichend sicher eingestuft werden (siehe unten). Die beiden Hauptgründe dafür sind:
- HwBinder-Server führen keine Clientauthentifizierung durch, da HIDL derzeit keine Informationen zur UID des Anrufers preisgibt. Selbst wenn HIDL solche Daten offenlegen würde, arbeiten viele HwBinder-Dienste entweder auf einer Ebene unterhalb der von Apps (z. B. HALs) oder dürfen für die Autorisierung nicht auf die App-Identität angewiesen sein. Aus Sicherheitsgründen wird daher standardmäßig davon ausgegangen, dass jeder HwBinder-Dienst alle seine Clients als gleichermaßen berechtigt behandelt, die vom Dienst angebotenen Vorgänge auszuführen.
- HAL-Server (eine Teilmenge der HwBinder-Dienste) enthalten Code mit einer höheren Häufigkeit von Sicherheitsproblemen als
system/core
-Komponenten und haben Zugriff auf die unteren Schichten des Stacks (bis hinunter zur Hardware). Dadurch steigt die Wahrscheinlichkeit, das Android-Sicherheitsmodell zu umgehen.
Safe-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 stellen keine Risiken im Zusammenhang mit Punkt 2 dar.hal_configstore_ISurfaceFlingerConfigs
. Dieser Dienst ist speziell für die Verwendung durch jede Domain konzipiert.hal_graphics_allocator_hwservice
. Diese Vorgänge werden auch vomsurfaceflinger
-Binderdienst angeboten, auf den Apps zugreifen dürfen.hal_omx_hwservice
. Dies ist eine HwBinder-Version desmediacodec
-Binder-Dienstes, auf den Apps zugreifen dürfen.hal_codec2_hwservice
. Dies ist eine neuere Version vonhal_omx_hwservice
.
Verwendbare Attribute
Alle hwservices
, die nicht als sicher eingestuft werden, haben das Attribut untrusted_app_visible_hwservice
. Die entsprechenden HAL-Server haben das Attribut untrusted_app_visible_halserver
. Auf Geräten mit Android 9 darf KEIN untrusted
-Attribut verwendet werden.
Empfehlung:
- Nicht vertrauenswürdige Apps sollten stattdessen mit einem Systemdienst kommunizieren, der mit der HIDL HAL des Anbieters kommuniziert. Apps können beispielsweise mit
binderservicedomain
kommunizieren, dannmediaserver
(einebinderservicedomain
) mit derhal_graphics_allocator
.ODER
- Apps, die direkten Zugriff auf
vendor
HALs benötigen, sollten eine eigene vom Anbieter definierte SEPolicy-Domain haben.
Dateiattributtests
Android 9 enthält Buildzeittests, die dafür sorgen, dass alle Dateien an bestimmten Speicherorten die entsprechenden Attribute haben (z. B. dass alle Dateien in sysfs
das erforderliche sysfs_type
-Attribut haben).
Plattformrichtlinien
Die Plattformrichtlinie ist der Kern der Einhaltung des Architekturmodells von Android 8.0, ohne einfach die Vereinigung der Plattformrichtlinien von Version 1 und Version 2 beizubehalten. Anbietern wird ein Teil der Plattformrichtlinie angezeigt, der verwendbare Typen und Attribute sowie Regeln für diese Typen und Attribute enthält. Diese werden dann Teil der Anbieterrichtlinie (vendor_sepolicy.cil
).
Typen und Regeln werden in der vom Anbieter generierten Richtlinie automatisch in attribute_vN
übersetzt, sodass alle von der Plattform bereitgestellten Typen Versionsattribute sind (Attribute werden jedoch nicht versioniert). Die Plattform ist dafür verantwortlich, die von ihr bereitgestellten Typen den entsprechenden Attributen zuzuordnen, damit die Anbieterrichtlinie weiterhin funktioniert und die für eine bestimmte Version bereitgestellten Regeln enthalten sind. Die Kombination aus öffentlichen Plattformrichtlinien und Anbieterrichtlinien erfüllt das Ziel des Architekturmodells von Android 8.0, unabhängige Plattform- und Anbieter-Builds zu ermöglichen.
Zuordnung zu Attributketten
Wenn Sie Attribute verwenden, um Richtlinienversionen zuzuordnen, wird ein Typ einem Attribut oder mehreren Attributen zugeordnet. So ist sichergestellt, dass auf Objekte, die mit dem Typ gekennzeichnet sind, über Attribute zugegriffen werden kann, die ihren vorherigen Typen entsprechen.
Wenn Sie Versionsinformationen vor dem Richtlinienschreiber verbergen möchten, müssen Sie die versionierten Attribute automatisch generieren und den entsprechenden Typen zuweisen. Im häufigen Fall statischer Typen ist das ganz einfach: type_foo
wird type_foo_v1
zugeordnet.
Bei einer Objektlabeländerung wie sysfs
→ sysfs_A
oder mediaserver
→ audioserver
ist das Erstellen dieser Zuordnung nicht trivial (siehe die Beispiele oben). Die Verantwortlichen für die Plattformrichtlinien müssen festlegen, wie die Zuordnung an Übergangspunkten für Objekte erstellt wird. Dazu müssen sie die Beziehung zwischen Objekten und ihren zugewiesenen Labels verstehen und bestimmen, wann dies der Fall ist. Aus Gründen der Abwärtskompatibilität muss diese Komplexität auf Plattformebene verwaltet werden. Dies ist die einzige Partition, die aktualisiert werden kann.
Versionsvorgänger
Aus Gründen der Einfachheit wird auf der Android-Plattform eine SEPolicy-Version veröffentlicht, wenn ein neuer Release-Zweig erstellt wird. Wie oben beschrieben, ist die Versionsnummer in PLATFORM_SEPOLICY_VERSION
enthalten und hat das Format MM.nn
. Dabei entspricht MM
dem SDK-Wert und nn
ist ein privater Wert, der in /platform/system/sepolicy.
gespeichert wird. Beispiele: 19.0
für KitKat, 21.0
für Lollipop, 22.0
für Lollipop-MR1, 23.0
für Marshmallow, 24.0
für Nougat, 25.0
für Nougat-MR1, 26.0
für Oreo, 27.0
für Oreo-MR1 und 28.0
für Android 9.
Uprevs sind nicht immer ganze Zahlen. Wenn beispielsweise eine MR-Änderung an einer Version eine inkompatible Änderung an system/sepolicy/public
, aber keine API-Änderung erfordert, könnte diese Sepolicy-Version vN.1
sein. Die Version in einem Entwicklungszweig ist eine 10000.0
, die niemals in Geräten verwendet werden darf.
Android kann die älteste Version beim Upgraden verwerfen. Um zu ermitteln, wann eine Version eingestellt werden sollte, kann Android die Anzahl der Geräte mit Anbieterrichtlinien erfassen, auf denen diese Android-Version ausgeführt wird und die noch wichtige Plattformupdates erhalten. Wenn die Anzahl unter einem bestimmten Grenzwert liegt, wird die Version eingestellt.
Auswirkungen mehrerer Attribute auf die Leistung
Wie unter https://github.com/SELinuxProject/cil/issues/9 beschrieben, führt eine große Anzahl von Attributen, die einem Typ zugewiesen sind, bei einem Richtliniencache-Miss zu Leistungsproblemen.
Dieses Problem wurde bestätigt. Daher wurden Änderungen an Android 8.0 vorgenommen, um Attribute zu entfernen, die der Richtlinie vom Richtliniencompiler hinzugefügt wurden, sowie ungenutzte Attribute. Durch diese Änderungen wurden Leistungseinbrüche behoben.
system_ext public and product public policy
Ab Android 11 können die Partitionen system_ext
und product
ihre angegebenen öffentlichen Typen in die Anbieterpartition exportieren. Wie bei den öffentlichen Richtlinien der Plattform verwendet der Anbieter Typen und Regeln, die automatisch in die versionierten Attribute übersetzt werden, z. B. von type
in type_N
, wobei N
die Version der Plattform ist, auf der die Anbieterpartition erstellt wurde.
Wenn die system_ext
- und product
-Partitionen auf derselben Plattformversion N
basieren, generiert das Buildsystem Basiszuordnungsdateien für system_ext/etc/selinux/mapping/N.cil
und product/etc/selinux/mapping/N.cil
, die Identitätszuordnungen von type
zu type_N
enthalten. Der Anbieter kann über das versionierte Attribut type_N
auf type
zugreifen.
Wenn nur die Partitionen system_ext
und product
aktualisiert werden, z. B. von N
auf N+1
(oder höher), während der Anbieter bei N
bleibt, verliert er möglicherweise den Zugriff auf die Typen der Partitionen system_ext
und product
. Um Unterbrechungen zu vermeiden, sollten die Partitionen system_ext
und product
Zuordnungsdateien von konkreten Typen zu type_N
-Attributen enthalten. Jeder Partner ist für die Pflege der Zuordnungsdateien verantwortlich, wenn er den N
-Anbieter mit N+1
(oder höher) system_ext
- und product
-Partitionen unterstützen möchte.
Dazu müssen Partner Folgendes tun:
- Kopieren Sie die generierten Basiszuordnungsdateien aus den Partitionen
N
,system_ext
undproduct
in das entsprechende Quellverzeichnis. - Ändern Sie die Zuordnungsdateien nach Bedarf.
-
Installieren Sie die Zuordnungsdateien auf den Partitionen
N+1
(oder höher)system_ext
undproduct
.
Angenommen, N
system_ext
hat einen öffentlichen Typ namens foo_type
. Dann sieht system_ext/etc/selinux/mapping/N.cil
in der Partition N
system_ext
so aus:
(typeattributeset foo_type_N (foo_type)) (expandtypeattribute foo_type_N true) (typeattribute foo_type_N)
Wenn bar_type
zu N+1
system_ext hinzugefügt wird und bar_type
für den Anbieter N
mit foo_type
abgeglichen werden soll, kann N.cil
über
(typeattributeset foo_type_N (foo_type))
to
(typeattributeset foo_type_N (foo_type bar_type))
und dann auf der Partition N+1
system_ext installiert.
Der N
-Anbieter kann weiterhin auf foo_type
und bar_type
von N+1
system_ext zugreifen.
SELinux-Kontexte kennzeichnen
Um die Unterscheidung zwischen Plattform- und Anbieter-SEPolicy zu unterstützen, werden SELinux-Kontextdateien vom System unterschiedlich erstellt, um sie voneinander zu trennen.
Dateikontexte
Mit Android 8.0 wurden die folgenden Änderungen für file_contexts
eingeführt:
- Um zusätzlichen Kompilierungsoverhead auf dem Gerät während des Starts zu vermeiden, existiert
file_contexts
nicht mehr in der Binärform. Stattdessen sind sie lesbare reguläre Ausdrucksdateien wie{property, service}_contexts
(wie vor Version 7.0). - Die
file_contexts
-Dateien sind auf zwei Dateien aufgeteilt:plat_file_contexts
- Android-Plattform
file_context
ohne gerätespezifische Labels, mit Ausnahme der Labels für Teile der/vendor
-Partition, die genau gekennzeichnet werden müssen, damit die sepolicy-Dateien ordnungsgemäß funktionieren. - Muss sich in der
system
-Partition unter/system/etc/selinux/plat_file_contexts
auf dem Gerät befinden und muss voninit
zusammen mit dem Anbieterfile_context
zu Beginn geladen werden.
- Android-Plattform
vendor_file_contexts
- Gerätespezifische
file_context
, die durch Kombinieren vonfile_contexts
aus den Verzeichnissen erstellt werden, auf die in denBoardconfig.mk
-Dateien des Geräts durchBOARD_SEPOLICY_DIRS
verwiesen wird. - Muss in der Partition
vendor
unter/vendor/etc/selinux/vendor_file_contexts
installiert und voninit
zusammen mit der Plattformfile_context
zu Beginn geladen werden.
- Gerätespezifische
Property-Kontexte
Unter Android 8.0 wird die property_contexts
in zwei Dateien aufgeteilt:
plat_property_contexts
- Android-Plattform
property_context
ohne gerätespezifische Labels - Muss sich in der
system
-Partition unter/system/etc/selinux/plat_property_contexts
befinden und muss voninit
zusammen mit dem Anbieterproperty_contexts
zu Beginn geladen werden.
- Android-Plattform
vendor_property_contexts
- Gerätespezifische
property_context
, die durch Kombinieren vonproperty_contexts
aus den Verzeichnissen erstellt wird, auf die in denBoardconfig.mk
-Dateien des Geräts durchBOARD_SEPOLICY_DIRS
verwiesen wird. - Muss sich in der
vendor
-Partition unter/vendor/etc/selinux/vendor_property_contexts
befinden und voninit
zusammen mit der Plattformproperty_context
zu Beginn geladen werden.
- Gerätespezifische
Dienstkontexte
Unter Android 8.0 wird die service_contexts
auf die folgenden Dateien aufgeteilt:
plat_service_contexts
- Android-plattformspezifische
service_context
für dieservicemanager
. Dieservice_context
hat keine gerätespezifischen Labels. - Muss sich in der
system
-Partition unter/system/etc/selinux/plat_service_contexts
befinden und zusammen mit dem Anbieterservice_contexts
vonservicemanager
zu Beginn geladen werden.
- Android-plattformspezifische
vendor_service_contexts
- Gerätespezifische
service_context
, die durch Zusammenführen vonservice_contexts
aus den Verzeichnissen erstellt wurden, auf die in denBoardconfig.mk
-Dateien des Geräts durchBOARD_SEPOLICY_DIRS
verwiesen wird. - Muss sich in der
vendor
-Partition unter/vendor/etc/selinux/vendor_service_contexts
befinden und vonservicemanager
zusammen mit der Plattformservice_contexts
zu Beginn geladen werden. servicemanager
sucht zwar beim Start nach dieser Datei, für ein vollständig konformesTREBLE
-Gerät darfvendor_service_contexts
jedoch NICHT vorhanden sein. Das liegt daran, dass alle Interaktionen zwischenvendor
- undsystem
-Prozessen überhwservicemanager
/hwbinder
erfolgen MÜSSEN.
- Gerätespezifische
plat_hwservice_contexts
- Android-Plattform
hwservice_context
fürhwservicemanager
ohne gerätespezifische Labels. - Muss sich in der
system
-Partition unter/system/etc/selinux/plat_hwservice_contexts
befinden und zusammen mit dervendor_hwservice_contexts
vonhwservicemanager
zu Beginn geladen werden.
- Android-Plattform
vendor_hwservice_contexts
- Gerätespezifische
hwservice_context
, die durch Zusammenführen vonhwservice_contexts
aus den Verzeichnissen erstellt wurden, auf die in denBoardconfig.mk
-Dateien des Geräts durchBOARD_SEPOLICY_DIRS
verwiesen wird. - Muss sich in der
vendor
-Partition unter/vendor/etc/selinux/vendor_hwservice_contexts
befinden und am Anfang zusammen mit derplat_service_contexts
vonhwservicemanager
geladen werden.
- Gerätespezifische
vndservice_contexts
- Gerätespezifische
service_context
für dievndservicemanager
, die durch Kombinieren vonvndservice_contexts
aus den Verzeichnissen erstellt wird, auf dieBOARD_SEPOLICY_DIRS
imBoardconfig.mk
des Geräts verweist. - Diese Datei muss sich in der Partition
vendor
unter/vendor/etc/selinux/vndservice_contexts
befinden und zu Beginn vonvndservicemanager
geladen werden.
- Gerätespezifische
Seapp-Kontexte
Unter Android 8.0 wird die 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
- Android-Plattform
vendor_seapp_contexts
- Gerätespezifische Erweiterung der Plattform
seapp_context
, die durch Kombinieren vonseapp_contexts
aus den Verzeichnissen erstellt wird, auf die in denBoardconfig.mk
-Dateien des Geräts überBOARD_SEPOLICY_DIRS
verwiesen wird. - Muss sich in der
vendor
-Partition unter/vendor/etc/selinux/vendor_seapp_contexts
befinden.
- Gerätespezifische Erweiterung der Plattform
MAC-Berechtigungen
Unter Android 8.0 wird die mac_permissions.xml
in zwei Dateien aufgeteilt:
- Bahnsteig
mac_permissions.xml
- Android-Plattform
mac_permissions.xml
ohne gerätespezifische Änderungen. - Muss sich in der
system
-Partition unter/system/etc/selinux/.
befinden
- Android-Plattform
- Nicht Plattform-bezogen
mac_permissions.xml
- Gerätespezifische Erweiterung der Plattform
mac_permissions.xml
, die ausmac_permissions.xml
erstellt wurde und sich in den Verzeichnissen befindet, auf die in denBoardconfig.mk
-Dateien des Geräts überBOARD_SEPOLICY_DIRS
verwiesen wird. - Muss sich in der
vendor
-Partition unter/vendor/etc/selinux/.
befinden
- Gerätespezifische Erweiterung der Plattform