SELinux ist so eingerichtet, dass der Zugriff standardmäßig verweigert wird. Das bedeutet, dass jeder Zugriff, für den es einen Hook im Kernel gibt, explizit durch eine Richtlinie erlaubt werden muss. Eine Richtliniendatei enthält also eine große Menge an Informationen zu Regeln, Typen, Klassen, Berechtigungen und mehr. Eine vollständige Betrachtung von SELinux geht über den Rahmen dieses Dokuments hinaus, aber das Wissen, wie Richtlinienregeln geschrieben werden, ist jetzt unerlässlich, wenn neue Android-Geräte eingerichtet werden. Es gibt bereits viele Informationen zu SELinux. Vorschläge für Ressourcen finden Sie unter Unterstützende Dokumentation.
Schlüsseldateien
Um SELinux zu aktivieren, integrieren Sie den aktuellen Android-Kernel und fügen Sie dann die Dateien aus dem Verzeichnis system/sepolicy ein. Wenn sie kompiliert werden, umfassen diese Dateien die SELinux-Kernelsicherheitsrichtlinie und decken das Upstream-Android-Betriebssystem ab.
Im Allgemeinen sollten Sie die system/sepolicy
-Dateien nicht direkt ändern. Fügen Sie stattdessen Ihre eigenen gerätespezifischen Richtliniendateien im Verzeichnis /device/manufacturer/device-name/sepolicy
hinzu oder bearbeiten Sie sie dort. Unter Android 8.0 und höher sollten sich die Änderungen, die Sie an diesen Dateien vornehmen, nur auf die Richtlinie in Ihrem Anbieterverzeichnis auswirken. Weitere Informationen zur Trennung von öffentlicher SEPolicy in Android 8.0 und höher finden Sie unter SEPolicy in Android 8.0+ anpassen. Unabhängig von der Android-Version werden weiterhin diese Dateien geändert:
Richtliniendateien
Dateien, die mit *.te
enden, sind SELinux-Richtlinienquelldateien, in denen Domains und ihre Labels definiert werden. Möglicherweise müssen Sie neue Richtliniendateien in /device/manufacturer/device-name/sepolicy
erstellen. Versuchen Sie jedoch, vorhandene Dateien zu aktualisieren, wenn möglich.
Kontextdateien
In Kontextdateien geben Sie Labels für Ihre Objekte an.
file_contexts
weist Dateien Labels zu und wird von verschiedenen Userspace-Komponenten verwendet. Wenn Sie neue Richtlinien erstellen, erstellen oder aktualisieren Sie diese Datei, um Dateien neue Labels zuzuweisen. Wenn Sie neuefile_contexts
anwenden möchten, erstellen Sie das Dateisystem-Image neu oder führen Sierestorecon
für die neu zu kennzeichnende Datei aus. Bei Upgrades werden Änderungen anfile_contexts
automatisch auf die System- und Nutzerdatenpartitionen angewendet. Änderungen können auch automatisch beim Upgrade auf andere Partitionen angewendet werden, indem Sierestorecon_recursive
-Aufrufe zu Ihrer Datei „init.board.rc“ hinzufügen, nachdem die Partition schreibgeschützt gemountet wurde.- Mit
genfs_contexts
werden Labels für Dateisysteme wieproc
odervfat
zugewiesen, die keine erweiterten Attribute unterstützen. Diese Konfiguration wird als Teil der Kernelrichtlinie geladen. Änderungen werden jedoch möglicherweise nicht für In-Core-Inodes wirksam. Daher ist ein Neustart oder das Trennen und erneute Einbinden des Dateisystems erforderlich, um die Änderung vollständig anzuwenden. Bestimmten Bereitstellungen können auch bestimmte Labels zugewiesen werden, z. B.vfat
mit der Optioncontext=mount
. property_contexts
weist Android-Systemeigenschaften Labels zu, um zu steuern, welche Prozesse sie festlegen können. Diese Konfiguration wird beim Starten desinit
-Prozesses gelesen.- Mit
service_contexts
werden Android-Binder-Diensten Labels zugewiesen, um zu steuern, welche Prozesse eine Binder-Referenz für den Dienst hinzufügen (registrieren) und finden (nachschlagen) können. Diese Konfiguration wird beim Starten desservicemanager
-Prozesses gelesen. seapp_contexts
weist Labels für App-Prozesse und/data/data
-Verzeichnisse zu. Diese Konfiguration wird bei jedem App-Start vomzygote
-Prozess und beim Start voninstalld
gelesen.- Mit
mac_permissions.xml
wird Apps basierend auf ihrer Signatur und optional ihrem Paketnamen das Tagseinfo
zugewiesen. Das Tagseinfo
kann dann als Schlüssel in der Dateiseapp_contexts
verwendet werden, um allen Apps mit diesemseinfo
-Tag ein bestimmtes Label zuzuweisen. Diese Konfiguration wird beim Start vonsystem_server
gelesen. - Mit
keystore2_key_contexts
werden Labels für Keystore 2-Namespaces zugewiesen. Diese Namespaces werden vomkeystore2
-Daemon erzwungen. Der Keystore hat immer UID-/AID-basierte Namespaces bereitgestellt. Keystore 2 erzwingt zusätzlich die in sepolicy definierten Namespaces. Eine detaillierte Beschreibung des Formats und der Konventionen dieser Datei finden Sie hier.
Makefile „BoardConfig.mk“
Nachdem Sie Richtlinien- und Kontextdateien bearbeitet oder hinzugefügt haben, müssen Sie die /device/manufacturer/device-name/BoardConfig.mk
-Makefile aktualisieren, damit sie auf das Unterverzeichnis sepolicy
und jede neue Richtliniendatei verweist.
Weitere Informationen zu den BOARD_SEPOLICY
-Variablen finden Sie in der
Datei system/sepolicy/README
.
BOARD_SEPOLICY_DIRS += \ <root>/device/manufacturer/device-name/sepolicy BOARD_SEPOLICY_UNION += \ genfs_contexts \ file_contexts \ sepolicy.te
Nach dem Rebuild ist SELinux auf Ihrem Gerät aktiviert. Sie können jetzt entweder Ihre SELinux-Richtlinien an Ihre eigenen Ergänzungen des Android-Betriebssystems anpassen, wie unter Anpassung beschrieben, oder Ihre vorhandene Einrichtung überprüfen, wie unter Validierung beschrieben.
Wenn die neuen Richtliniendateien und BoardConfig.mk-Updates vorhanden sind, werden die neuen Richtlinieneinstellungen automatisch in die endgültige Kernel-Richtliniendatei eingebunden. Weitere Informationen dazu, wie sepolicy auf dem Gerät erstellt wird, finden Sie unter sepolicy erstellen.
Implementierung
Erste Schritte mit SELinux:
- Aktivieren Sie SELinux im Kernel:
CONFIG_SECURITY_SELINUX=y
- Ändern Sie den Parameter „kernel_cmdline“ oder „bootconfig“ so, dass:
oderBOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
Dies dient nur der ersten Entwicklung von Richtlinien für das Gerät. Nachdem Sie eine erste Bootstrap-Richtlinie haben, entfernen Sie diesen Parameter, damit Ihr Gerät die CTS-Tests besteht oder nicht besteht.BOARD_BOOTCONFIG := androidboot.selinux=permissive
- Starten Sie das System im permissiven Modus und sehen Sie nach, welche Ablehnungen beim Start auftreten:
Unter Ubuntu 14.04 oder höher: Unter Ubuntu 12.04:adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
adb pull /sys/fs/selinux/policy adb logcat -b all | audit2allow -p policy
- Prüfen Sie die Ausgabe auf Warnungen, die
init: Warning! Service name needs a SELinux domain defined; please fix!
ähneln. Eine Anleitung und Tools finden Sie unter Validierung. - Geräte und andere neue Dateien identifizieren, die mit Labels versehen werden müssen
- Verwenden Sie vorhandene oder neue Labels für Ihre Objekte. Sehen Sie sich die
*_contexts
-Dateien an, um zu sehen, wie die Elemente zuvor gekennzeichnet wurden, und verwenden Sie Ihr Wissen über die Bedeutung der Labels, um ein neues zuzuweisen. Im Idealfall ist dies ein vorhandenes Label, das den Richtlinien entspricht. Manchmal ist jedoch ein neues Label erforderlich und es müssen Regeln für den Zugriff auf dieses Label festgelegt werden. Fügen Sie Ihre Labels den entsprechenden Kontextdateien hinzu. - Ermitteln Sie Domains/Prozesse, die eigene Sicherheitsdomains haben sollten.
Wahrscheinlich müssen Sie für jede eine völlig neue Richtlinie erstellen. Alle von
init
abgeleiteten Dienste sollten beispielsweise eigene haben. Die folgenden Befehle helfen dabei, die noch laufenden Dienste zu ermitteln (aber ALLE Dienste müssen so behandelt werden):
adb shell su -c ps -Z | grep init
adb shell su -c dmesg | grep 'avc: '
- Sehen Sie sich
init.device.rc
an, um Domains ohne Domaintyp zu ermitteln. Geben Sie ihnen frühzeitig im Entwicklungsprozess eine Domain, um zu vermeiden, dass Regeln fürinit
hinzugefügt werden oderinit
-Zugriffe mit Zugriffen verwechselt werden, die in ihrer eigenen Richtlinie enthalten sind. - Richten Sie
BOARD_CONFIG.mk
so ein, dassBOARD_SEPOLICY_*
-Variablen verwendet werden. Weitere Informationen zur Einrichtung finden Sie in der README-Datei insystem/sepolicy
. - Sehen Sie sich die Dateien „init.device.rc“ und „fstab.device“ an und prüfen Sie, ob jede Verwendung von
mount
einem korrekt gekennzeichneten Dateisystem entspricht oder ob die Optioncontext= mount
angegeben ist. - Sehen Sie sich jede Ablehnung an und erstellen Sie eine SELinux-Richtlinie, um sie richtig zu behandeln. Beispiele für die Anpassung
Beginnen Sie mit den Richtlinien im AOSP und bauen Sie dann auf diesen auf, um Ihre eigenen Anpassungen vorzunehmen. Weitere Informationen zur Richtlinienstrategie und eine genauere Beschreibung einiger dieser Schritte finden Sie unter SELinux-Richtlinie schreiben.
Anwendungsfälle
Hier sind einige konkrete Beispiele für Exploits, die Sie bei der Entwicklung Ihrer eigenen Software und der zugehörigen SELinux-Richtlinien berücksichtigen sollten:
Symlinks:Da Symlinks als Dateien angezeigt werden, werden sie oft als Dateien gelesen, was zu Exploits führen kann. Einige privilegierte Komponenten wie init
ändern beispielsweise die Berechtigungen bestimmter Dateien, manchmal auch zu offen.
Angreifer können diese Dateien dann durch Symlinks zu Code ersetzen, den sie kontrollieren, sodass sie beliebige Dateien überschreiben können. Wenn Sie jedoch wissen, dass Ihre App niemals einen Symlink durchläuft, können Sie dies mit SELinux verhindern.
Systemdateien:Berücksichtigen Sie die Klasse von Systemdateien, die nur vom Systemserver geändert werden sollten. Da netd
, init
und vold
jedoch als Root ausgeführt werden, können sie auf diese Systemdateien zugreifen. Wenn netd
kompromittiert wird, könnten auch diese Dateien und möglicherweise der Systemserver selbst kompromittiert werden.
Mit SELinux können Sie diese Dateien als Datendateien für Systemserver identifizieren.
Daher hat nur der Systemserver Lese-/Schreibzugriff auf sie.
Selbst wenn netd
manipuliert würde, könnte es nicht zu der Systemserverdomain wechseln und auf diese Systemdateien zugreifen, obwohl es als Root ausgeführt wird.
App-Daten:Ein weiteres Beispiel ist die Klasse von Funktionen, die als Root ausgeführt werden müssen, aber nicht auf App-Daten zugreifen dürfen. Das ist sehr nützlich, da weitreichende Behauptungen aufgestellt werden können, z. B. dass bestimmte Domains, die nicht mit App-Daten zusammenhängen, nicht auf das Internet zugreifen dürfen.
setattr:Bei Befehlen wie chmod
und chown
können Sie die Gruppe von Dateien identifizieren, in denen die zugehörige Domain setattr
ausführen kann. Alles, was darüber hinausgeht, kann durch diese Änderungen verboten werden, auch für Nutzer mit Root-Zugriff. Eine App kann also chmod
und chown
für die mit app_data_files
gekennzeichneten Geräte ausführen, nicht aber für shell_data_files
oder system_data_files
.