Der Init-Prozess hat nahezu uneingeschränkte Berechtigungen und verwendet Eingabescripts sowohl aus den System- als auch aus den Anbieterpartitionen, um das System während des Bootvorgangs zu initialisieren. Dieser Zugriff verursacht ein großes Loch in der Treble-System-/Anbieteraufteilung, da Anbieterscripts init anweisen können, auf Dateien, Eigenschaften usw. zuzugreifen, die nicht Teil der stabilen System-Anbieter-Anwendungs-Binärschnittstelle (ABI) sind.
Vendor init soll diese Lücke schließen. Dazu wird eine separate SELinux-Domain (Security-Enhanced Linux) vendor_init
verwendet, um Befehle in /vendor
mit anbieterspezifischen Berechtigungen auszuführen.
Mechanismus
„Vendor init“ teilt früh im Bootvorgang einen Subprozess von „init“ mit dem SELinux-Kontext u:r:vendor_init:s0
ab. Dieser SELinux-Kontext hat deutlich weniger Berechtigungen als der Standard-init-Kontext und sein Zugriff ist auf Dateien, Eigenschaften usw. beschränkt, die entweder anbieterspezifisch sind oder zur stabilen ABI des Systemanbieters gehören.
Init prüft jedes geladene Skript, um festzustellen, ob sein Pfad mit /vendor
beginnt. Falls ja, kennzeichnet es es mit einem Hinweis, dass seine Befehle im init-Kontext des Anbieters ausgeführt werden müssen. Jede integrierte Initialisierung wird mit einem booleschen Wert gekennzeichnet, der angibt, ob der Befehl im Unterprozess der Anbieter-Init ausgeführt werden muss:
- Die meisten Befehle, die auf das Dateisystem zugreifen, sind so gekennzeichnet, dass sie im Anbieter-init-Subprozess ausgeführt werden. Sie unterliegen daher der SEPolicy des Anbieters init.
- Die meisten Befehle, die sich auf den internen Init-Status auswirken (z.B. Starten und Stoppen von Diensten), werden im normalen Init-Prozess ausgeführt. Bei diesen Befehlen wird darauf hingewiesen, dass ein Anbieterskript ihn aufruft, um seine eigenen Berechtigungen außerhalb von SELinux zu verarbeiten.
Die Hauptverarbeitungsschleife von init enthält eine Prüfung, ob ein Befehl, der im Anbieter-Subprozess ausgeführt werden soll und aus einem Anbieter-Script stammt, über die Inter-Process-Kommunikation (IPC) an den Anbieter-init-Subprozess gesendet wird, der den Befehl ausführt und das Ergebnis an init zurücksendet.
Anbieter-init verwenden
Die Anbieter-Init-Funktion ist standardmäßig aktiviert und ihre Einschränkungen gelten für alle Init-Scripts in der Partition /vendor
. Die Anbieterinitialisierung sollte für Anbieter transparent sein, deren Scripts bereits nicht auf systemeigene Dateien, Properties usw. zugreifen.
Wenn die Befehle in einem bestimmten Anbieterskript jedoch gegen die Einschränkungen der Anbieterinitis verstoßen, schlagen die Befehle fehl. Bei fehlgeschlagenen Befehlen gibt es im Kernelprotokoll (mit dmesg sichtbar) eine Zeile von init, die auf den Fehler hinweist. Bei jedem Befehl, der aufgrund der SELinux-Richtlinie fehlgeschlagen ist, wird eine SELinux-Prüfung durchgeführt. Beispiel für einen Fehler, der eine SELinux-Prüfung enthält:
type=1400 audit(1511821362.996:9): avc: denied { search } for pid=540 comm="init" name="nfc" dev="sda45" ino=1310721 scontext=u:r:vendor_init:s0 tcontext=u:object_r:nfc_data_file:s0 tclass=dir permissive=0 init: Command 'write /data/nfc/bad_file_access 1234' action=boot (/vendor/etc/init/hw/init.walleye.rc:422) took 2ms and failed: Unable to write to file '/data/nfc/bad_file_access': open() failed: Permission denied
Wenn ein Befehl fehlschlägt, haben Sie zwei Möglichkeiten:
- Wenn der Befehl aufgrund einer beabsichtigten Einschränkung fehlschlägt (z. B. wenn der Befehl auf eine Systemdatei oder ‑eigenschaft zugreift), muss er auf eine Treble-kompatible Weise neu implementiert werden und nur über stabile Schnittstellen ausgeführt werden. Neverallow-Regeln verhindern das Hinzufügen von Berechtigungen für den Zugriff auf Systemdateien, die nicht Teil der stabilen ABI des Systemanbieters sind.
- Wenn das SELinux-Label neu ist und ihm keine Berechtigungen in der systemspezifischen
vendor_init.te
gewährt wurden und es auch nicht durch die neverallow-Regeln ausgeschlossen wurde, können dem neuen Label Berechtigungen in der gerätespezifischenvendor_init.te
gewährt werden.
Bei Geräten, die vor Android 9 gestartet wurden, können die Regeln vom Typ „neverallows“ umgangen werden, indem das data_between_core_and_vendor_violators
-Typattribut der gerätespezifischen vendor_init.te
-Datei hinzugefügt wird.
Speicherorte der Codes
Der Großteil der Logik für die Anbieter-init-IPC befindet sich in system/core/init/subcontext.cpp.
Die Tabelle mit den Befehlen befindet sich in der Klasse BuiltinFunctionMap
in system/core/init/builtins.cpp und enthält Annotationen, die angeben, ob der Befehl im Anbieter-init-Unterprozess ausgeführt werden muss.
Die SEPolicy für die Anbieterinitialisierung ist in den privaten (system/sepolicy/private/vendor_init.te) und öffentlichen (system/sepolicy/public/vendor_init.te) Verzeichnissen in system/sepolicy aufgeteilt.