SELinux ist auf „Default-Deny“ eingestellt, was bedeutet, dass jeder einzelne Zugriff, für den es einen Hook im Kernel hat, durch die Richtlinie explizit zugelassen werden muss. Das bedeutet, dass eine Richtliniendatei eine große Menge an Informationen zu Regeln, Typen, Klassen, Berechtigungen und mehr enthält. Eine vollständige Betrachtung von SELinux würde den Rahmen dieses Dokuments sprengen, aber ein Verständnis dafür, wie Richtlinienregeln geschrieben werden, ist jetzt unerlässlich, wenn neue Android-Geräte eingeführt werden. Es gibt bereits viele Informationen zu SELinux. Empfohlene Ressourcen finden Sie in der Begleitdokumentation .
Schlüsseldateien
Um SELinux zu aktivieren, integrieren Sie den neuesten Android-Kernel und dann die im Verzeichnis system/sepolicy gefundenen Dateien. Beim Kompilieren umfassen diese Dateien die SELinux-Kernel-Sicherheitsrichtlinie 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. In Android 8.0 und höher sollten sich die Änderungen, die Sie an diesen Dateien vornehmen, nur auf die Richtlinien in Ihrem Anbieterverzeichnis auswirken. Weitere Einzelheiten zur Trennung der öffentlichen Sepolicy in Android 8.0 und höher finden Sie unter Anpassen von SEPolicy in Android 8.0+ . Unabhängig von der Android-Version ändern Sie immer noch diese Dateien:
Richtliniendateien
Dateien, die mit *.te
enden, sind SELinux-Richtlinienquelldateien, die Domänen und ihre Bezeichnungen definieren. Möglicherweise müssen Sie neue Richtliniendateien in /device/ manufacturer / device-name /sepolicy
erstellen, Sie sollten jedoch versuchen, vorhandene Dateien nach Möglichkeit zu aktualisieren.
Kontextdateien
In Kontextdateien geben Sie Beschriftungen für Ihre Objekte an.
-
file_contexts
weist Dateien Beschriftungen zu und wird von verschiedenen Userspace-Komponenten verwendet. Wenn Sie neue Richtlinien erstellen, erstellen oder aktualisieren Sie diese Datei, um den Dateien neue Bezeichnungen zuzuweisen. Um neuefile_contexts
anzuwenden, erstellen Sie das Dateisystem-Image neu oder führen Sierestorecon
für die Datei aus, die neu beschriftet werden soll. Bei Upgrades werden Änderungen anfile_contexts
im Rahmen des Upgrades automatisch auf die System- und Benutzerdatenpartitionen angewendet. Änderungen können auch automatisch beim Upgrade auf andere Partitionen angewendet werden, indem Sierestorecon_recursive
-Aufrufe zu Ihrer Init-Instanz hinzufügen. board .rc-Datei, nachdem die Partition mit Lese-/Schreibzugriff gemountet wurde. -
genfs_contexts
weist Dateisystemen Labels zu, z. B.proc
odervfat
, die keine erweiterten Attribute unterstützen. Diese Konfiguration wird als Teil der Kernel-Richtlinie geladen, aber Änderungen werden möglicherweise nicht für In-Core-Inodes wirksam, sodass ein Neustart oder ein Unmounten und erneutes Mounten des Dateisystems erforderlich ist, um die Änderung vollständig anzuwenden. Bestimmten Mounts können auch bestimmte Labels zugewiesen werden, z. B.vfat
mithilfe der Optioncontext=mount
. -
property_contexts
weist Android-Systemeigenschaften Beschriftungen zu, um zu steuern, welche Prozesse sie festlegen können. Diese Konfiguration wird beim Start vominit
Prozess gelesen. -
service_contexts
weist Android-Binder-Diensten Beschriftungen zu, um zu steuern, welche Prozesse eine Binder-Referenz für den Dienst hinzufügen (registrieren) und suchen (suchen) können. Diese Konfiguration wird beim Start vomservicemanager
Prozess gelesen. -
seapp_contexts
weist App-Prozessen und/data/data
Verzeichnissen Beschriftungen zu. Diese Konfiguration wird vomzygote
Prozess bei jedem App-Start gelesen und voninstalld
beim Start. -
mac_permissions.xml
weist Apps basierend auf ihrer Signatur und optional ihrem Paketnamen einseinfo
Tag zu. Dasseinfo
Tag kann dann als Schlüssel in der Dateiseapp_contexts
verwendet werden, um allen Apps mit diesemseinfo
Tag eine bestimmte Bezeichnung zuzuweisen. Diese Konfiguration wird beim Start vonsystem_server
gelesen. -
keystore2_key_contexts
weist Keystore 2.0-Namespaces Beschriftungen zu. Dieser Namespace wird vom keystore2-Daemon erzwungen. Keystore stellt seit jeher UID/AID-basierte Namespaces bereit. Keystore 2.0 erzwingt zusätzlich durch Sepolicy definierte Namespaces. Eine detaillierte Beschreibung des Formats und der Konventionen dieser Datei finden Sie hier .
BoardConfig.mk-Makefile
Aktualisieren Sie nach dem Bearbeiten oder Hinzufügen von Richtlinien- und Kontextdateien Ihr Makefile /device/ manufacturer / device-name /BoardConfig.mk
um auf das Unterverzeichnis sepolicy
und jede neue Richtliniendatei zu verweisen. 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 Neuaufbau ist Ihr Gerät mit SELinux aktiviert. Sie können jetzt entweder Ihre SELinux-Richtlinien anpassen, um Ihre eigenen Ergänzungen zum Android-Betriebssystem zu berücksichtigen, wie unter „Anpassung“ beschrieben, oder Ihr bestehendes Setup ü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 integriert. Weitere Informationen darüber, wie Sepolicy auf dem Gerät erstellt wird, finden Sie unter Erstellen von Sepolicy .
Implementierung
Um mit SELinux zu beginnen:
- Aktivieren Sie SELinux im Kernel:
CONFIG_SECURITY_SELINUX=y
- Ändern Sie den Parameter „kernel_cmdline“ oder „bootconfig“ wie folgt:
BOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
oderBOARD_BOOTCONFIG := androidboot.selinux=permissive
Dies dient nur der anfänglichen Entwicklung einer Richtlinie für das Gerät. Nachdem Sie eine erste Bootstrap-Richtlinie erstellt haben, entfernen Sie diesen Parameter, damit Ihr Gerät die Richtlinie durchsetzt, andernfalls wird CTS fehlschlagen. - Starten Sie das System permissiv und sehen Sie, welche Ablehnungen beim Booten auftreten:
Unter Ubuntu 14.04 oder neuer:adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
Unter Ubuntu 12.04:adb pull /sys/fs/selinux/policy adb logcat -b all | audit2allow -p policy
- Überprüfen Sie die Ausgabe auf Warnungen, die
init: Warning! Service name needs a SELinux domain defined; please fix!
Anweisungen und Tools finden Sie unter Validierung . - Identifizieren Sie Geräte und andere neue Dateien, die eine Kennzeichnung benötigen.
- Nutzen Sie bestehende oder neue Beschriftungen für Ihre Objekte. Schauen Sie sich die
*_contexts
Dateien an, um zu sehen, wie Dinge zuvor beschriftet wurden, und nutzen Sie die Kenntnis der Beschriftungsbedeutungen, um eine neue zuzuweisen. Im Idealfall handelt es sich dabei um ein vorhandenes Label, das in die Richtlinie passt. Manchmal ist jedoch ein neues Label erforderlich, und es sind Regeln für den Zugriff auf dieses Label erforderlich. Fügen Sie Ihre Beschriftungen den entsprechenden Kontextdateien hinzu. - Identifizieren Sie Domänen/Prozesse, die über eigene Sicherheitsdomänen verfügen sollten. Sie müssen wahrscheinlich für jeden eine völlig neue Richtlinie schreiben. Alle aus
init
hervorgegangenen Dienste sollten beispielsweise ihre eigenen haben. Die folgenden Befehle helfen dabei, diejenigen aufzudecken, die weiterhin ausgeführt werden (aber ALLE Dienste benötigen eine solche Behandlung):adb shell su -c ps -Z | grep init
adb shell su -c dmesg | grep 'avc: '
- Überprüfen Sie
init. device .rc
, um alle Domänen zu identifizieren, die keinen Domänentyp haben. Geben Sie ihnen zu Beginn Ihres Entwicklungsprozesses eine Domäne, um zu vermeiden, dass Sie Regeln zuinit
hinzufügen oder auf andere Weiseinit
Zugriffe mit denen verwechseln, die in ihrer eigenen Richtlinie enthalten sind. - Richten Sie
BOARD_CONFIG.mk
für die Verwendung vonBOARD_SEPOLICY_*
Variablen ein. Weitere Informationen zum Einrichten finden Sie in der README-Datei untersystem/sepolicy
. - Untersuchen Sie die Init. device .rc und fstab. device und stellen Sie sicher, dass jede Verwendung von
mount
einem ordnungsgemäß gekennzeichneten Dateisystem entspricht oder dass einecontext= mount
Option angegeben ist. - Gehen Sie jede Ablehnung durch und erstellen Sie eine SELinux-Richtlinie, um jede ordnungsgemäß zu behandeln. Sehen Sie sich die Beispiele unter „Anpassung“ an.
Sie sollten mit den Richtlinien im AOSP beginnen und dann für Ihre eigenen Anpassungen darauf aufbauen. Weitere Informationen zur Richtlinienstrategie und einen genaueren Blick auf einige dieser Schritte finden Sie unter Schreiben einer SELinux-Richtlinie .
Anwendungsfälle
Hier sind konkrete Beispiele für Exploits, die Sie bei der Erstellung Ihrer eigenen Software und zugehörigen SELinux-Richtlinien berücksichtigen sollten:
Symlinks – Da Symlinks als Dateien erscheinen, werden sie oft als Dateien gelesen, was zu Exploits führen kann. Beispielsweise ändern einige privilegierte Komponenten wie init
die Berechtigungen bestimmter Dateien, sodass sie manchmal übermäßig geöffnet sind.
Angreifer könnten diese Dateien dann durch symbolische Links zu Code ersetzen, den sie kontrollieren, wodurch der Angreifer beliebige Dateien überschreiben kann. Wenn Sie jedoch wissen, dass Ihre Anwendung niemals einen symbolischen Link passieren wird, können Sie ihr dies mit SELinux verbieten.
Systemdateien – Berücksichtigen Sie die Klasse der 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 also netd
kompromittiert würde, könnten diese Dateien und möglicherweise auch der Systemserver selbst gefährdet werden.
Mit SELinux können Sie diese Dateien als Systemserver-Datendateien identifizieren. Daher ist der Systemserver die einzige Domäne, die Lese-/Schreibzugriff darauf hat. Selbst wenn netd
kompromittiert wurde, konnte es die Domänen nicht zur Systemserverdomäne 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 keinen Zugriff auf App-Daten haben sollten. Dies ist äußerst nützlich, da weitreichende Aussagen getroffen werden können, beispielsweise dass bestimmten Domains, die nichts mit Anwendungsdaten zu tun haben, der Zugriff auf das Internet untersagt ist.
setattr – Für Befehle wie chmod
und chown
können Sie den Satz von Dateien identifizieren, in denen die zugehörige Domäne setattr
ausführen kann. Alles andere könnte von diesen Änderungen ausgeschlossen werden, sogar durch Root. Daher kann eine Anwendung chmod
und chown
für diejenigen mit der Bezeichnung app_data_files
ausführen, jedoch nicht für shell_data_files
oder system_data_files
.