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 Script, um festzustellen, ob sein Pfad mit /vendor
beginnt. Ist dies der Fall, wird es mit einem Hinweis versehen, dass seine Befehle im Init-Kontext des Anbieters ausgeführt werden müssen. Jedes integrierte Init-Kommando ist mit einem booleschen Wert versehen, der angibt, ob der Befehl im Init-Subprozess des Anbieters ausgeführt werden muss oder nicht:
- 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. Diese Befehle werden darüber informiert, dass sie von einem Anbieterscript aufgerufen werden, um eine eigene Berechtigungsverwaltung außerhalb von SELinux auszuführen.
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 Befehle in einem bestimmten Anbieterscript jedoch gegen die Einschränkungen der Anbieterinitiierung verstoßen, schlagen sie 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 mit einer SELinux-Prüfung:
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 des 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.
Codespeicherorte
Der Großteil der Logik für die Anbieter-init-IPC befindet sich in system/core/init/subcontext.cpp.
Die Befehlstabelle befindet sich in der Klasse BuiltinFunctionMap
in system/core/init/builtins.cpp und enthält Anmerkungen, 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.