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. Es ist jedoch wichtig, zu wissen, wie Richtlinienregeln geschrieben werden, wenn neue Android-Geräte eingerichtet werden. Es gibt bereits viele Informationen zu SELinux. Unter Unterstützende Dokumentation finden Sie Vorschläge für Ressourcen.
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. Nach der Kompilierung bilden diese Dateien die SELinux-Kernelsicherheitsrichtlinie und decken das Upstream-Android-Betriebssystem ab.
Im Allgemeinen sollten Sie die system/sepolicy-Dateien nicht direkt bearbeiten. Fügen Sie stattdessen Ihre eigenen gerätespezifischen Richtliniendateien im Verzeichnis /device/manufacturer/device-name/sepolicy hinzu oder bearbeiten Sie sie dort. In 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_contextsweist 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_contextsanwenden möchten, erstellen Sie das Dateisystem-Image neu oder führen Sierestoreconfür die neu zu kennzeichnende Datei aus. Bei Upgrades werden Änderungen anfile_contextsautomatisch 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_contextswerden Labels wieprocodervfatDateisystemen 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.vfatmit der Optioncontext=mount. property_contextsweist Android-Systemeigenschaften Labels zu, um zu steuern, welche Prozesse sie festlegen können. Diese Konfiguration wird beim Start vominit-Prozess gelesen.service_contextsweist Android-Binder-Diensten Labels zu, um zu steuern, welche Prozesse eine Binder-Referenz für den Dienst hinzufügen (registrieren) und finden (nachschlagen) können. Diese Konfiguration wird beim Start vomservicemanager-Prozess gelesen.- Mit
seapp_contextswerden Labels für App-Prozesse und/data/data-Verzeichnisse zugewiesen. Diese Konfiguration wird bei jedem App-Start vomzygote-Prozess und beim Start voninstalldgelesen. - Mit
mac_permissions.xmlwird Apps basierend auf ihrer Signatur und optional ihrem Paketnamen das Tagseinfozugewiesen. Das Tagseinfokann dann als Schlüssel in der Dateiseapp_contextsverwendet werden, um allen Apps mit diesemseinfo-Tag ein bestimmtes Label zuzuweisen. Diese Konfiguration wird beim Start vonsystem_servergelesen. keystore2_key_contextsweist Keystore 2-Namespaces Labels zu. Diese Namespaces werden vomkeystore2-Daemon erzwungen. Der Schlüsselspeicher 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 Ihr /device/manufacturer/device-name/BoardConfig.mk-Makefile aktualisieren, damit es 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 Neuerstellen 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
initabgeleiteten Dienste sollten beispielsweise eigene haben. Mit den folgenden Befehlen können Sie die Dienste ermitteln, die weiterhin ausgeführt werden (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.rcan, um Domains ohne Domaintyp zu finden. Weisen Sie ihnen frühzeitig im Entwicklungsprozess eine Domain zu, um zu vermeiden, dass Regeln fürinithinzugefügt werden oderinit-Zugriffe mit Zugriffen verwechselt werden, die in ihrer eigenen Richtlinie enthalten sind. - Richten Sie
BOARD_CONFIG.mkso ein, dassBOARD_SEPOLICY_*-Variablen verwendet werden. Weitere Informationen zur Einrichtung finden Sie in der README-Datei insystem/sepolicy. - Prüfen Sie die Dateien „init.device.rc“ und „fstab.device“ und achten Sie darauf, dass jede Verwendung von
mounteinem korrekt gekennzeichneten Dateisystem entspricht oder dass die Optioncontext= mountangegeben ist. - Sehen Sie sich jede Ablehnung an und erstellen Sie eine SELinux-Richtlinie, um sie richtig zu behandeln. Beispiele finden Sie unter 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, z. B. init, ändern 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 einem Symlink folgt, 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 kompromittiert 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 in Verbindung stehen, 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.