Richtlinienkompatibilität

In diesem Artikel wird beschrieben, wie Android die Richtlinienkompatibilitätsprobleme mit Plattform-OTAs handhabt, bei denen sich neue Plattform-SELinux-Einstellungen von alten Anbieter-SELinux-Einstellungen unterscheiden können.

Das Treble-basierte SELinux-Richtliniendesign berücksichtigt eine binäre Unterscheidung zwischen Plattform- und Anbieterrichtlinie ; Das Schema wird komplizierter, wenn Anbieterpartitionen Abhängigkeiten erzeugen, wie beispielsweise platform < vendor < oem .

In Android 8.0 und höher ist die globale Richtlinie von SELinux in private und öffentliche Komponenten unterteilt. Öffentliche Komponenten bestehen aus der Richtlinie und der zugehörigen Infrastruktur, die garantiert für eine Plattformversion verfügbar sind. Diese Richtlinie wird Anbieterrichtlinienautoren offengelegt, damit Anbieter eine Anbieterrichtliniendatei erstellen können, die in Kombination mit der von der Plattform bereitgestellten Richtlinie zu einer voll funktionsfähigen Richtlinie für ein Gerät führt.

  • Für die Versionierung wird die exportierte Plattform-öffentliche Richtlinie als Attribute geschrieben.
  • Um das Schreiben von Richtlinien zu vereinfachen, werden exportierte Typen im Rahmen des Richtlinienerstellungsprozesses in versionierte Attribute umgewandelt. Öffentliche Typen können auch direkt bei Kennzeichnungsentscheidungen verwendet werden, die von Herstellerkontextdateien bereitgestellt werden.

Android verwaltet eine Zuordnung zwischen exportierten konkreten Typen in der Plattformrichtlinie und den entsprechenden versionierten Attributen für jede Plattformversion . Dadurch wird sichergestellt, dass beim Kennzeichnen von Objekten mit einem Typ kein Verhalten verletzt wird, das durch die öffentliche Plattformrichtlinie in einer früheren Version garantiert wurde. Diese Zuordnung wird aufrechterhalten, indem eine Zuordnungsdatei für jede Plattformversion auf dem neuesten Stand gehalten wird, die Attributmitgliedschaftsinformationen für jeden Typ enthält, der in der öffentlichen Richtlinie exportiert wird.

Eigentum und Kennzeichnung von Objekten

Beim Anpassen der Richtlinie in Android 8.0 und höher muss der Besitz für jedes Objekt klar definiert werden, um Plattform- und Anbieterrichtlinie getrennt zu halten. Wenn der Anbieter beispielsweise /dev/foo und die Plattform in einem nachfolgenden OTA dann /dev/foo bezeichnet, wird es ein undefiniertes Verhalten geben. Für SELinux manifestiert sich dies als eine Beschriftungskollision. Der Geräteknoten kann nur ein einziges Label haben, das in das zuletzt angewendete Label aufgelöst wird. Infolge:

  • Prozesse, die Zugriff auf das nicht erfolgreich angewendete Label benötigen , verlieren den Zugriff auf die Ressource.
  • Prozesse, die Zugriff auf die Datei erhalten , können abbrechen, weil der falsche Geräteknoten erstellt wurde.

Systemeigenschaften können auch Namenskollisionen verursachen, die zu undefiniertem Verhalten auf dem System führen können (sowie für die SELinux-Kennzeichnung). Kollisionen zwischen Plattform- und Anbieterbezeichnungen können für jedes Objekt auftreten, das eine SELinux-Bezeichnung hat, einschließlich Eigenschaften, Dienste, Prozesse, Dateien und Sockets. Um diese Probleme zu vermeiden, definieren Sie das Eigentum an diesen Objekten klar.

Zusätzlich zu Labelkollisionen können auch SELinux-Typ-/Attributnamen kollidieren. Eine Typ-/Attributnamenskollision führt immer zu einem Richtlinien-Compiler-Fehler.

Typ/Attribut-Namensraum

SELinux erlaubt keine mehrfachen Deklarationen desselben Typs/Attributs. Richtlinien mit doppelten Deklarationen können nicht kompiliert werden. Um Typ- und Attributnamenskollisionen zu vermeiden, sollten alle Herstellerdeklarationen einen Namensraum haben, der mit np_ .

type foo, domain; → type np_foo, domain;

Besitz von Systemeigenschaften und Prozessbezeichnungen

Das Vermeiden von Beschriftungskollisionen lässt sich am besten mithilfe von Eigenschaftsnamensräumen lösen. Um Plattformeigenschaften einfach zu identifizieren und Namenskonflikte beim Umbenennen oder Hinzufügen von exportierten Plattformeigenschaften zu vermeiden, stellen Sie sicher, dass alle Anbietereigenschaften ihre eigenen Präfixe haben:

Art der Immobilie Akzeptable Präfixe
Kontrolleigenschaften ctl.vendor.
ctl.start$vendor.
ctl.stop$vendor.
init.svc.vendor.
lesen-beschreibbar vendor.
schreibgeschützt ro.vendor.
ro.boot.
ro.hardware.
hartnäckig persist.vendor.

Anbieter können weiterhin ro.boot.* (das aus der Kernel-cmdline stammt) und ro.hardware.* (eine offensichtlich hardwarebezogene Eigenschaft) verwenden.

Alle Anbieterdienste in init rc-Dateien sollten den vendor. für Dienste in init rc-Dateien von Nicht-Systempartitionen. Ähnliche Regeln werden auf die SELinux-Bezeichnungen für die Anbietereigenschaften ( vendor_ für die Anbietereigenschaften) angewendet.

Dateibesitz

Das Verhindern von Kollisionen für Dateien ist eine Herausforderung, da sowohl die Plattform- als auch die Herstellerrichtlinie üblicherweise Labels für alle Dateisysteme bereitstellen. Im Gegensatz zur Typbenennung ist das Namespacen von Dateien nicht praktikabel, da viele von ihnen vom Kernel erstellt werden. Um diese Kollisionen zu vermeiden, befolgen Sie die Benennungshinweise für Dateisysteme in diesem Abschnitt. Für Android 8.0 sind dies Empfehlungen ohne technische Durchsetzung. Diese Empfehlungen werden zukünftig durch die Vendor Test Suite (VTS) durchgesetzt.

System (/System)

Nur das System-Image muss Bezeichnungen für /system Komponenten über file_contexts , service_contexts usw. bereitstellen. Wenn Bezeichnungen für /system Komponenten in der /vendor -Richtlinie hinzugefügt werden, ist eine reine Framework-OTA-Aktualisierung möglicherweise nicht möglich.

Anbieter (/vendor)

Die AOSP-SELinux-Richtlinie kennzeichnet bereits Teile der vendor , mit der die Plattform interagiert, wodurch das Schreiben von SELinux-Regeln für Plattformprozesse ermöglicht wird, um in der Lage zu sein, mit Teilen der vendor zu kommunizieren und/oder darauf zuzugreifen. Beispiele:

/vendor Pfad Von der Plattform bereitgestelltes Etikett Plattformprozesse je nach Label
/vendor(/. * )? vendor_file Alle HAL-Clients in 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 bestimmte Regeln befolgt werden (erzwungen durch neverallows ), wenn zusätzliche Dateien in der vendor gekennzeichnet werden:

  • vendor_file muss die Standardbezeichnung für alle Dateien in der vendor sein. Die Plattformrichtlinie erfordert dies für den Zugriff auf Passthrough-HAL-Implementierungen.
  • Alle neuen exec_types , die in der vendor -Partition über Vendor SEPolicy hinzugefügt werden, müssen das vendor_file_type Attribut haben. Dies wird durch Neverallows erzwungen.
  • Um Konflikte mit zukünftigen Plattform-/Framework-Updates zu vermeiden, vermeiden Sie es, andere Dateien als exec_types in der vendor zu kennzeichnen.
  • Alle Bibliotheksabhängigkeiten für AOSP-identifizierte gleiche Prozess-HALs müssen als same_process_hal_file.

Procfs (/proc)

Dateien in /proc können nur mit dem Label genfscon gekennzeichnet werden. In Android 7.0 verwendeten sowohl die Plattform- als auch die Herstellerrichtlinie genfscon , um Dateien in procfs zu kennzeichnen.

Empfehlung: Nur Plattformrichtlinienlabels /proc . Wenn vendor Zugriff auf Dateien in /proc benötigen, die derzeit mit dem Standardlabel ( proc ) gekennzeichnet sind, sollte die Anbieterrichtlinie sie nicht explizit kennzeichnen und stattdessen den generischen proc -Typ verwenden, um Regeln für Anbieterdomänen hinzuzufügen. Dadurch können die Plattform-Updates zukünftige Kernel-Schnittstellen aufnehmen, die durch procfs verfügbar gemacht werden, und sie explizit nach Bedarf kennzeichnen.

Debugfs (/sys/kernel/debug)

Debugfs können sowohl in file_contexts als auch in genfscon . In Android 7.0 bis Android 10 debugfs sowohl das Plattform- als auch das Anbieterlabel.

In Android 11 kann nicht auf debugfs zugegriffen oder auf Produktionsgeräten bereitgestellt werden. Gerätehersteller sollten debugfs entfernen.

Tracefs (/sys/kernel/debug/tracing)

Tracefs können sowohl in file_contexts als auch in genfscon . In Android 7.0 bezeichnet nur die Plattform tracefs .

Empfehlung: Nur die Plattform darf tracefs .

Sysfs (/sys)

Dateien in /sys können sowohl mit file_contexts als auch mit genfscon werden. In Android 7.0 verwenden sowohl die Plattform als auch der Anbieter file_contexts und 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 gekennzeichnet werden. In Android 7.0 sowohl Plattform- als auch Anbieterlabeldateien hier.

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

Rootfs (/)

Dateien in / können in file_contexts gekennzeichnet werden. In Android 7.0 sowohl Plattform- als auch Anbieterlabeldateien hier.

Empfehlung: Nur das System darf Dateien in / kennzeichnen.

Daten (/daten)

Daten werden durch eine Kombination aus file_contexts und seapp_contexts .

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

Kompatibilitätsattribute

Die 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, aber dieser Typ kann mehrere Attribute haben.

Richtlinien werden hauptsächlich in Bezug auf vorhandene Typen geschrieben:

allow source_type target_type:target_class permission(s);

Dies funktioniert, weil die Richtlinie mit Wissen aller Art geschrieben wurde. Wenn jedoch die Anbieterrichtlinie und die Plattformrichtlinie bestimmte Typen verwenden und sich die Bezeichnung eines bestimmten Objekts in nur einer dieser Richtlinien ändert, enthält die andere möglicherweise eine Richtlinie, die zuvor Zugriff erlangt oder verloren hat. Zum 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 geändert werden in:

File_contexts:
/sys/A   u:object_r:sysfs_A:s0

Obwohl die Richtlinie des Anbieters dieselbe bleiben würde, würde die v_domain den Zugriff aufgrund der fehlenden Richtlinie für den neuen Typ sysfs_A verlieren.

Indem wir eine Richtlinie in Form von Attributen definieren, können wir dem zugrunde liegenden Objekt einen Typ geben, der ein Attribut hat, das der Richtlinie sowohl für den Plattform- als auch für den Anbietercode entspricht. Dies kann für alle Typen durchgeführt werden, um effektiv eine Attributrichtlinie zu erstellen, in der konkrete Typen niemals verwendet werden. In der Praxis ist dies nur für die Teile der Richtlinie erforderlich, die sich zwischen Plattform und Anbieter überschneiden, die als öffentliche Plattformrichtlinie definiert und bereitgestellt werden, die als Teil der Anbieterrichtlinie erstellt wird.

Das Definieren öffentlicher Richtlinien als versionierte Attribute erfüllt zwei Richtlinienkompatibilitätsziele:

  • Stellen Sie sicher, dass der Anbietercode nach dem Plattform-Update weiterhin funktioniert . Erreicht durch Hinzufügen von Attributen zu konkreten Typen für Objekte, die denen entsprechen, auf die sich der Anbietercode stützte, wodurch der Zugriff erhalten bleibt.
  • Möglichkeit, die Richtlinie zu verwerfen . Erreicht durch eine klare Abgrenzung von Richtliniensätzen in Attribute, die entfernt werden können, sobald die Version, der sie entsprechen, nicht mehr unterstützt wird. Die Entwicklung kann in der Plattform fortgesetzt werden, da bekannt ist, dass die alte Richtlinie noch in der Anbieterrichtlinie vorhanden ist und automatisch entfernt wird, wenn/falls sie aktualisiert wird.

Beschreibbarkeit von Richtlinien

Um das Ziel zu erreichen, für die Richtlinienentwicklung keine Kenntnis bestimmter Versionsänderungen zu erfordern, enthält Android 8.0 eine Zuordnung zwischen Plattform-öffentlichen Richtlinientypen und ihren Attributen. Der Typ foo wird dem Attribut foo_v N , wobei N die Zielversion ist. vN entspricht der Build-Variablen PLATFORM_SEPOLICY_VERSION und hat das Format MM.NN , wobei MM der Plattform-SDK-Nummer entspricht und NN eine plattformspezifische Version der Richtlinie ist.

Attribute in der öffentlichen Richtlinie sind nicht versioniert, sondern existieren als API, auf der Plattform- und Anbieterrichtlinien aufbauen können, um die Schnittstelle zwischen den beiden Partitionen stabil zu halten. Sowohl Plattform- als auch Anbieterrichtlinienautoren können weiterhin Richtlinien schreiben, wie sie heute geschrieben sind.

Plattformöffentliche Richtlinie exportiert als allow source_foo target_bar: class perm ; ist Teil der Lieferantenrichtlinie. Während der Kompilierung (die die entsprechende Version enthält) wird sie in die Richtlinie umgewandelt, die an den Herstellerteil des Geräts geht (dargestellt in der umgewandelten Common Intermediate Language (CIL)):

 (allow source_foo_vN target_bar_vN (class (perm)))

Da die Herstellerrichtlinie der Plattform nie voraus ist, sollte sie sich nicht um frühere Versionen kümmern. Die Plattformrichtlinie muss jedoch wissen, wie weit die Herstellerrichtlinie zurückliegt, Attribute zu ihren Typen hinzufügen und eine Richtlinie festlegen, die den versionierten Attributen entspricht.

Richtlinienunterschiede

Das automatische Erstellen von Attributen durch Hinzufügen von _v N am Ende jedes Typs bewirkt nichts ohne Zuordnung von Attributen zu Typen über Versionsunterschiede hinweg. Android verwaltet eine Zuordnung zwischen Versionen für Attribute und eine Zuordnung von Typen zu diesen Attributen. Dies geschieht in den oben genannten Mapping-Dateien mit Anweisungen wie (CIL):

(typeattributeset foo_vN (foo))

Plattform-Upgrades

Der folgende Abschnitt beschreibt Szenarien für Plattform-Upgrades.

Gleiche Typen

Dieses Szenario tritt auf, wenn ein Objekt Bezeichnungen in Richtlinienversionen nicht ändert. Dies ist für Quell- und Zieltypen gleich und kann mit /dev/binder gesehen werden, das in allen Releases als binder_device bezeichnet wird. Es wird in der transformierten Politik dargestellt als:

binder_device_v1 … binder_device_vN

Beim Upgrade von v1v2 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 V1-Anbieterrichtlinie (CIL):

(typeattribute binder_device_v1)
(allow binder_device_v1 …)

In der V2-Anbieterrichtlinie (CIL):

(typeattribute binder_device_v2)
(allow binder_device_v2 …)
Neue Typen

Dieses Szenario tritt auf, wenn die Plattform einen neuen Typ hinzugefügt hat, was beim Hinzufügen neuer Funktionen oder während der Richtlinienhärtung passieren kann.

  • Neue Funktion . Wenn der Typ ein zuvor nicht vorhandenes Objekt kennzeichnet (z. B. einen neuen Dienstprozess), hat der Anbietercode zuvor nicht direkt damit interagiert, sodass keine entsprechende Richtlinie vorhanden ist. Das neue Attribut, das dem Typ entspricht, hat kein Attribut in der vorherigen Version und würde daher keinen Eintrag in der Zuordnungsdatei benötigen, die auf diese Version abzielt.
  • Politikverhärtung . Wenn der Typ eine Richtlinienhärtung darstellt, muss das neue Typattribut mit einer Kette von Attributen verknüpft werden, die dem vorherigen entspricht (ähnlich dem vorherigen Beispiel, in dem /sys/A von sysfs in sysfs_A ). Herstellercode stützt sich auf eine Regel, die den Zugriff auf sysfs ermöglicht, und muss diese Regel als Attribut des neuen Typs enthalten.

Beim Upgrade von v1v2 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 V1-Anbieterrichtlinie (CIL):

(typeattribute sysfs_v1)
(allow … sysfs_v1 …)

In der V2-Anbieterrichtlinie (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, was passieren kann, wenn das zugrunde liegende Objekt:

  • Bleibt, bekommt aber ein anderes Label.
  • Wird von der Plattform entfernt.

Während der Richtlinienlockerung wird ein Typ entfernt und das mit diesem Typ gekennzeichnete Objekt erhält eine andere, bereits vorhandene Bezeichnung. Dies stellt eine Zusammenführung von Attributzuordnungen dar: Der Herstellercode muss weiterhin über das Attribut, das er früher besaß, auf das zugrunde liegende Objekt zugreifen können, aber der Rest des Systems muss nun mit seinem neuen Attribut darauf zugreifen können.

Wenn das Attribut, auf das es umgestellt wurde, neu ist, dann ist die Umbenennung dasselbe wie im Fall des neuen Typs, außer dass, wenn ein vorhandenes Etikett verwendet wird, das Hinzufügen des alten Attributs neuer Typ dazu führen würde, dass andere Objekte ebenfalls mit diesem Typ beschriftet werden neu zugänglich sein. Dies wird im Wesentlichen von der Plattform erledigt und wird als akzeptabler Kompromiss angesehen, um die Kompatibilität aufrechtzuerhalten.

(typeattribute sysfs_v1)
(allow … sysfs_v1 …)

Beispielversion 1: Typen reduzieren (sysfs_A entfernen)

Beim Upgrade von v1v2 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 V1-Anbieterrichtlinie (CIL):

(typeattribute sysfs_A_v1)
(allow … sysfs_A_v1 …)
(typeattribute sysfs_v1)
(allow … sysfs_v1 …)

In der V2-Anbieterrichtlinie (CIL):

(typeattribute sysfs_v2)
(allow … sysfs_v2 …)

Beispiel Version 2: Komplett entfernen (Typ foo)

Beim Upgrade von v1v2 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 V1-Anbieterrichtlinie (CIL):

(typeattribute foo_v1)
(allow foo …)
(typeattribute sysfs_v1)
(allow sysfs_v1 …)

In der V2-Anbieterrichtlinie (CIL):

(typeattribute sysfs_v2)
(allow sysfs_v2 …)
Neue Klasse/Berechtigungen

Dieses Szenario tritt auf, wenn bei einem Plattform-Upgrade neue Richtlinienkomponenten eingeführt werden, die in früheren Versionen nicht vorhanden sind. Als Android beispielsweise den Objektmanager servicemanager hinzufügte, der die Berechtigungen zum Hinzufügen, Suchen und Auflisten erstellte, benötigten Vendor-Daemons, die sich beim servicemanager registrieren wollten, Berechtigungen, die nicht verfügbar waren. In Android 8.0 kann nur die Plattformrichtlinie neue Klassen und Berechtigungen hinzufügen.

Damit alle Domänen, die durch die Richtlinie des Anbieters hätten erstellt oder erweitert werden können, die neue Klasse ungehindert verwenden können, muss die Plattformrichtlinie eine Regel ähnlich der folgenden enthalten:

allow {domain -coredomain} *:new_class perm;

Dies kann sogar eine Richtlinie erfordern, die den Zugriff für alle Arten von Schnittstellen (öffentliche Richtlinien) zulässt, um sicherzustellen, dass das Anbieter-Image Zugriff erhält. Wenn dies zu einer inakzeptablen Sicherheitsrichtlinie führt (wie dies möglicherweise bei den Servicemanager-Änderungen der Fall ist), könnte möglicherweise ein Anbieter-Upgrade erzwungen werden.

Klasse/Berechtigungen entfernt

Dieses Szenario tritt auf, wenn ein Objektmanager entfernt wird (z. B. der ZygoteConnection Objektmanager) und sollte keine Probleme verursachen. Die Klasse und die Berechtigungen des Objektmanagers könnten in der Richtlinie definiert bleiben, bis die Herstellerversion sie nicht mehr verwendet. Dies erfolgt durch Hinzufügen der Definitionen zur entsprechenden Mapping-Datei.

Anbieteranpassung für neue/umgelabelte Typen

Neue Anbietertypen stehen im Mittelpunkt der Entwicklung von Anbieterrichtlinien, da sie benötigt werden, um neue Prozesse, Binärdateien, Geräte, Subsysteme und gespeicherte Daten zu beschreiben. Daher ist es zwingend erforderlich, die Erstellung von herstellerdefinierten Typen zuzulassen.

Da die Anbieterrichtlinie immer die älteste auf dem Gerät ist, müssen nicht alle Anbietertypen automatisch in Attribute in der Richtlinie konvertiert werden. Die Plattform verlässt sich nicht auf etwas, das in der Anbieterrichtlinie gekennzeichnet ist, da die Plattform keine Kenntnis davon hat; Die Plattform stellt jedoch die Attribute und öffentlichen Typen bereit, die sie verwendet, um mit Objekten zu interagieren, die mit diesen Typen gekennzeichnet sind (z. B. domain , sysfs_type usw.). Damit die Plattform weiterhin korrekt mit diesen Objekten interagiert, müssen die Attribute und Typen entsprechend angewendet und den anpassbaren Domänen (z. B. init ) möglicherweise spezifische Regeln hinzugefügt werden.

Attributänderungen für Android 9

Geräte, die auf Android 9 aktualisieren, können die folgenden Attribute verwenden, Geräte, die mit Android 9 gestartet werden, dürfen dies jedoch nicht.

Übertreterattribute

Android 9 enthält diese domänenbezogenen Attribute:

  • data_between_core_and_vendor_violators . Attribut für alle Domänen, die gegen die Anforderung verstoßen, Dateien nicht nach Pfad zwischen vendor und coredomains zu teilen. Plattform- und Anbieterprozesse sollten keine Dateien auf der Festplatte zur Kommunikation verwenden (instabile ABI). Empfehlung:
    • Der Anbietercode sollte /data/vendor verwenden.
    • Das System sollte /data/vendor nicht verwenden.
  • system_executes_vendor_violators . Attribut für alle Systemdomänen (außer init und shell domains ), die gegen die Anforderung verstoßen, keine Hersteller-Binärdateien auszuführen. Die Ausführung von Hersteller-Binärdateien hat eine instabile API. Die Plattform sollte Binärdateien des Anbieters nicht direkt ausführen. Empfehlung:
    • Solche Plattformabhängigkeiten von Anbieter-Binärdateien müssen hinter HIDL-HALs stehen.

      ODER

    • coredomains , die Zugriff auf Hersteller-Binärdateien benötigen, sollten in die Herstellerpartition verschoben werden und damit aufhören, coredomain zu sein.

Nicht vertrauenswürdige Attribute

Nicht vertrauenswürdige Apps, die willkürlichen Code hosten, sollten keinen Zugriff auf HwBinder-Dienste haben, mit Ausnahme derjenigen, die für den Zugriff von solchen Apps als ausreichend sicher gelten (siehe sichere Dienste unten). Die zwei Hauptgründe dafür sind:

  1. HwBinder-Server führen keine Clientauthentifizierung durch, da HIDL derzeit keine Anrufer-UID-Informationen offenlegt. Selbst wenn HIDL solche Daten offengelegt hat, arbeiten viele HwBinder-Dienste entweder auf einer Ebene unterhalb der von Apps (z. B. HALs) oder dürfen sich zur Autorisierung nicht auf die App-Identität verlassen. Aus Sicherheitsgründen wird daher standardmäßig davon ausgegangen, dass jeder HwBinder-Dienst alle seine Clients als gleichermaßen berechtigt behandelt, von dem Dienst angebotene Operationen auszuführen.
  2. HAL-Server (eine Teilmenge der HwBinder-Dienste) enthalten Code mit einer höheren Häufigkeit von Sicherheitsproblemen als system/core und haben Zugriff auf die unteren Schichten des Stapels (bis hinunter zur Hardware), wodurch die Möglichkeiten zur Umgehung des Android-Sicherheitsmodells erhöht werden .

Sichere Dienste

Zu den sicheren Diensten gehören:

  • same_process_hwservice . Diese Dienste laufen (per Definition) im Prozess des Clients und haben somit den gleichen Zugriff wie die Client-Domäne, in der der Prozess läuft.
  • coredomain_hwservice . Diese Dienste stellen keine Risiken dar, die mit Grund Nr. 2 verbunden sind.
  • hal_configstore_ISurfaceFlingerConfigs . Dieser Dienst ist speziell für die Verwendung durch beliebige Domains konzipiert.
  • hal_graphics_allocator_hwservice . Diese Vorgänge werden auch vom surfaceflinger Binder-Dienst angeboten, auf den Apps zugreifen dürfen.
  • hal_omx_hwservice . Dies ist eine HwBinder-Version des mediacodec -Binder-Dienstes, auf den Apps zugreifen dürfen.
  • hal_codec2_hwservice . Dies ist eine neuere Version von hal_omx_hwservice .

Verwendbare Attribute

Alle nicht als sicher hwservices haben das Attribut untrusted_app_visible_hwservice . Die entsprechenden HAL-Server haben das Attribut untrusted_app_visible_halserver . Geräte, die mit Android 9 gestartet werden, DÜRFEN KEINE der nicht untrusted Attribute verwenden.

Empfehlung:

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

    ODER

  • Apps, die direkten Zugriff auf vendor -HALs benötigen, sollten über eine eigene, vom Anbieter definierte Separity-Domäne verfügen.

Dateiattributtests

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

Plattformöffentliche Politik

Die Platform-Public-Richtlinie ist der Kern der Konformität mit dem Android 8.0-Architekturmodell, ohne einfach die Vereinigung der Plattformrichtlinien von v1 und v2 beizubehalten. Anbieter sind einer Teilmenge der Plattformrichtlinie ausgesetzt, die verwendbare Typen und Attribute und Regeln für diese Typen und Attribute enthält, die dann Teil der Anbieterrichtlinie werden (dh vendor_sepolicy.cil ).

Typen und Regeln werden in der vom Anbieter generierten Richtlinie automatisch in attribute_v N übersetzt, sodass alle von der Plattform bereitgestellten Typen versionierte Attribute sind (Attribute sind jedoch nicht versioniert). Die Plattform ist dafür verantwortlich, die von ihr bereitgestellten konkreten Typen den entsprechenden Attributen zuzuordnen, um sicherzustellen, dass die Anbieterrichtlinie weiterhin funktioniert und dass die für eine bestimmte Version bereitgestellten Regeln enthalten sind. Die Kombination aus öffentlicher Plattformrichtlinie und Anbieterrichtlinie erfüllt das Ziel des Android 8.0-Architekturmodells, unabhängige Plattform- und Anbieter-Builds zu ermöglichen.

Zuordnung zu Attributketten

Bei der Verwendung von Attributen zur Zuordnung zu Richtlinienversionen wird ein Typ einem Attribut oder mehreren Attributen zugeordnet, wodurch sichergestellt wird, dass mit dem Typ gekennzeichnete Objekte über Attribute zugänglich sind, die ihren vorherigen Typen entsprechen.

Das Ziel, Versionsinformationen vor dem Richtlinienautor zu verbergen, bedeutet, die versionierten Attribute automatisch zu generieren und sie den entsprechenden Typen zuzuweisen. Im allgemeinen Fall von statischen Typen ist dies einfach: type_foo wird auf type_foo_v1 .

Für eine Änderung der Objektbezeichnung wie sysfssysfs_A oder mediaserveraudioserver ist das Erstellen dieser Zuordnung nicht trivial (und wird in den obigen Beispielen beschrieben). Verwalter von Plattformrichtlinien müssen bestimmen, wie die Zuordnung an Übergangspunkten für Objekte erstellt wird, was ein Verständnis der Beziehung zwischen Objekten und ihren zugewiesenen Bezeichnungen und die Bestimmung des Zeitpunkts erfordert. Aus Gründen der Abwärtskompatibilität muss diese Komplexität auf der Plattformseite verwaltet werden, die die einzige Partition ist, die möglicherweise aktualisiert wird.

Version dreht hoch

Der Einfachheit halber veröffentlicht die Android-Plattform eine sepolicy-Version, wenn ein neuer Release-Zweig geschnitten wird. Wie oben beschrieben, ist die Versionsnummer in PLATFORM_SEPOLICY_VERSION enthalten und hat die Form MM.nn , wobei MM dem SDK-Wert entspricht und nn ein privater Wert ist, der in /platform/system/sepolicy. Zum Beispiel 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 es nicht immer ganze Zahlen. Wenn zum Beispiel ein MR-Bump zu einer Version eine inkompatible Änderung in system/sepolicy/public , aber keinen API-Bump erfordert, dann könnte diese sepolicy-Version sein: vN.1 . Die in einem Entwicklungszweig vorhandene Version ist eine Nie-zu-benutzen-in-Versand-Geräten 10000.0 .

Android kann die älteste Version beim Hochdrehen verwerfen. Für Eingaben darüber, wann eine Version veraltet sein soll, kann Android die Anzahl der Geräte mit Anbieterrichtlinien erfassen, auf denen diese Android-Version ausgeführt wird und die immer noch wichtige Plattformupdates erhalten. Wenn die Anzahl unter einem bestimmten Schwellenwert liegt, ist diese Version veraltet.

Auswirkungen auf die Leistung mehrerer Attribute

Wie in https://github.com/SELinuxProject/cil/issues/9 beschrieben, führt eine große Anzahl von Attributen, die einem Typ zugewiesen sind, zu Leistungsproblemen im Falle eines Richtlinien-Cache-Fehlers.

Dies wurde als Problem in Android bestätigt, daher wurden Änderungen an Android 8.0 vorgenommen, um Attribute zu entfernen, die der Richtlinie vom Richtlinien-Compiler hinzugefügt wurden, sowie nicht verwendete Attribute zu entfernen. Diese Änderungen haben Leistungsregressionen behoben.

System_ext public und product public policy

Ab Android 11 dürfen die Partitionen system_ext und product ihre ausgewiesenen öffentlichen Typen in die Vendor-Partition exportieren. Wie die öffentliche Richtlinie 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, gegen die die Anbieterpartition aufgebaut ist.

Wenn die Partitionen system_ext und product auf derselben Plattformversion N basieren, generiert das Build-System Basiszuordnungsdateien zu system_ext/etc/selinux/mapping/ N .cil und product/etc/selinux/mapping/ N .cil , die Identität enthalten Zuordnungen von type zu type_ N . Der Anbieter kann mit dem versionierten Attribut type_ N auf den type zugreifen.

Falls nur die system_ext- und Produktpartitionen aktualisiert werden, sagen wir N auf N+1 (oder später), während der Anbieter bei N bleibt, kann der Anbieter den Zugriff auf die Typen der system_ext- und Produktpartitionen verlieren. Um Brüche zu vermeiden, sollten die Partitionen system_ext und product Mapping-Dateien von konkreten Typen in type_ N Attribute bereitstellen. Jeder Partner ist für die Verwaltung der Zuordnungsdateien verantwortlich, wenn er N Anbieter mit N+1 (oder höher) system_ext- und Produktpartitionen unterstützen wird.

Dazu wird von den Partnern erwartet:

  1. Kopieren Sie die generierten Basiszuordnungsdateien aus N system_ext- und Produktpartitionen in ihren Quellbaum.
  2. Ändern Sie die Zuordnungsdateien nach Bedarf.
  3. Installieren Sie die Zuordnungsdateien auf N+1 (oder höher) system_ext- und Produktpartitionen.

Angenommen, N system_ext hat einen öffentlichen Typ namens foo_type . Dann 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 wenn bar_type foo_type für N Anbieter zugeordnet werden soll, kann N .cil aktualisiert werden

(typeattributeset foo_type_N (foo_type))

zu

(typeattributeset foo_type_N (foo_type bar_type))

und dann auf der Partition von N+1 system_ext installiert. N Anbieter können weiterhin auf foo_type und bar_type von N+1 system_ext zugreifen.

SELinux-Kontextkennzeichnung

Um die Unterscheidung zwischen Plattform- und Anbietertrennung zu unterstützen, erstellt das System SELinux-Kontextdateien anders, um sie getrennt zu halten.

Dateikontexte

Android 8.0 hat die folgenden Änderungen für file_contexts :

  • Um zusätzlichen Kompilierungsaufwand auf dem Gerät während des Bootens zu vermeiden, existieren file_contexts nicht mehr in binärer Form. Stattdessen sind sie lesbare Textdateien mit regulären Ausdrücken wie {property, service}_contexts (wie sie vor 7.0 waren).
  • Die file_contexts werden zwischen zwei Dateien aufgeteilt:
    • plat_file_contexts
      • file_context der Android-Plattform, der keine gerätespezifischen Bezeichnungen hat, mit Ausnahme der Bezeichnung von Teilen der /vendor -Partition, die genau bezeichnet werden müssen, um das ordnungsgemäße Funktionieren der sepolicy-Dateien sicherzustellen.
      • Muss sich in system unter /system/etc/selinux/plat_file_contexts auf dem Gerät befinden und von init beim Start zusammen mit dem Anbieter file_context werden.
    • vendor_file_contexts
      • file_context , der durch Kombinieren von file_contexts wird, die in den Verzeichnissen gefunden werden, auf die BOARD_SEPOLICY_DIRS in den Boardconfig.mk -Dateien des Geräts verweist.
      • Muss unter /vendor/etc/selinux/vendor_file_contexts in der vendor -Partition installiert und von init beim Start zusammen mit der Plattform file_context werden.

Eigenschaftskontexte

In Android 8.0 ist der property_contexts auf zwei Dateien aufgeteilt:

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

Servicekontexte

In Android 8.0 wird der service_contexts zwischen den folgenden Dateien aufgeteilt:

  • plat_service_contexts
    • Android-plattformspezifischer service_context für den servicemanager . Der service_context hat keine gerätespezifischen Labels.
    • Muss sich in system unter /system/etc/selinux/plat_service_contexts und vom servicemanager beim Start zusammen mit dem Anbieter service_contexts werden.
  • vendor_service_contexts
    • service_context , der durch Kombinieren von service_contexts wird, die in den Verzeichnissen gefunden werden, auf die BOARD_SEPOLICY_DIRS in den Boardconfig.mk -Dateien des Geräts verweist.
    • Muss sich in der vendor -Partition unter /vendor/etc/selinux/vendor_service_contexts und von servicemanager beim Start zusammen mit der Plattform service_contexts werden.
    • Obwohl der servicemanager beim Booten nach dieser Datei sucht, DARF für ein vollständig konformes TREBLE -Gerät der vendor_service_contexts NICHT existieren. Dies liegt daran, dass alle Interaktionen zwischen vendor und system über hwservicemanager /hwbinder laufen hwbinder .
  • plat_hwservice_contexts
    • Android-Plattform hwservice_context für hwservicemanager ohne gerätespezifische Bezeichnungen.
    • Muss sich in system unter /system/etc/selinux/plat_hwservice_contexts und vom hwservicemanager beim Start zusammen mit den vendor_hwservice_contexts werden.
  • vendor_hwservice_contexts
    • hwservice_context , der durch Kombinieren von hwservice_contexts wird, die in den Verzeichnissen gefunden werden, auf die BOARD_SEPOLICY_DIRS in den Boardconfig.mk -Dateien des Geräts verweist.
    • Muss sich in der vendor -Partition unter /vendor/etc/selinux/vendor_hwservice_contexts und vom hwservicemanager beim Start zusammen mit plat_service_contexts geladen werden.
  • vndservice_contexts
    • service_context für den vndservicemanager , der durch Kombinieren von vndservice_contexts erstellt wurde, die in den Verzeichnissen gefunden wurden, auf die BOARD_SEPOLICY_DIRS in Boardconfig.mk des Geräts Boardconfig.mk .
    • Diese Datei muss sich in der vendor -Partition unter /vendor/etc/selinux/vndservice_contexts und vom vndservicemanager beim Start geladen werden.

Seapp-Kontexte

In Android 8.0 ist die seapp_contexts auf zwei Dateien aufgeteilt:

  • plat_seapp_contexts
    • Android-Plattform seapp_context , die keine gerätespezifischen Änderungen aufweist.
    • Muss sich in system unter /system/etc/selinux/plat_seapp_contexts.
  • vendor_seapp_contexts
    • Gerätespezifische Erweiterung der Plattform seapp_context , die durch Kombinieren von seapp_contexts “ erstellt wurde, die in den Verzeichnissen gefunden wurden, auf die BOARD_SEPOLICY_DIRS in den „ Boardconfig.mk “-Dateien des Geräts verweist.
    • Muss sich in der vendor unter /vendor/etc/selinux/vendor_seapp_contexts .

MAC-Berechtigungen

In Android 8.0 ist die mac_permissions.xml auf zwei Dateien aufgeteilt:

  • Plattform mac_permissions.xml
    • Android-Plattform mac_permissions.xml , die keine gerätespezifischen Änderungen aufweist.
    • Muss sich in system unter /system/etc/selinux/.
  • Nicht-Plattform mac_permissions.xml
    • Gerätespezifische Erweiterung der Plattform mac_permissions.xml , die aus der mac_permissions.xml wurde, die in den Verzeichnissen zu finden ist, auf die BOARD_SEPOLICY_DIRS in den Boardconfig.mk -Dateien des Geräts verweist.
    • Muss sich in der vendor unter /vendor/etc/selinux/.