SELinux-Konzepte

Auf dieser Seite finden Sie Informationen zu den SELinux-Konzepten.

Obligatorische Zugriffssteuerung

Security-Enhanced Linux (SELinux) ist ein System zur obligatorischen Zugriffssteuerung (Mandatory Access Control, MAC) für das Linux-Betriebssystem. Als MAC-System unterscheidet es sich vom bekannten System zur benutzerbestimmbaren Zugriffssteuerung (Discretionary Access Control, DAC) von Linux. In einem DAC-System gibt es ein Konzept des Eigentums, bei dem ein Eigentümer einer bestimmten Ressource die zugehörigen Zugriffsberechtigungen steuert. Dies ist im Allgemeinen grob abgestuft und unterliegt einer unbeabsichtigten Rechteausweitung. Ein MAC-System fragt jedoch eine zentrale Stelle um eine Entscheidung zu allen Zugriffsversuchen.

SELinux wurde als Teil des Linux Security Module (LSM)-Frameworks implementiert, das verschiedene Kernelobjekte und sensible Aktionen erkennt, die auf ihnen ausgeführt werden. An dem Punkt, an dem jede dieser Aktionen ausgeführt werden soll, wird eine LSM-Hook-Funktion aufgerufen, um zu bestimmen, ob die Aktion basierend auf den Informationen, die in einem undurchsichtigen Sicherheitsobjekt gespeichert sind, zulässig sein soll. SELinux bietet eine Implementierung für diese Hooks und die Verwaltung dieser Sicherheitsobjekte, die in Kombination mit der eigenen Richtlinie die Zugriffsentscheidungen bestimmen.

Zusammen mit anderen Android-Sicherheitsmaßnahmen begrenzt die Android-Zugriffssteuerungsrichtlinie den potenziellen Schaden durch kompromittierte Geräte und Konten erheblich. Mit Tools wie der benutzerbestimmbaren und obligatorischen Zugriffssteuerung von Android können Sie eine Struktur erstellen, mit der sichergestellt wird, dass Ihre Software nur mit der minimal erforderlichen Berechtigungsstufe ausgeführt wird. Dadurch werden die Auswirkungen von Angriffen gemildert und die Wahrscheinlichkeit verringert, dass fehlerhafte Prozesse Daten überschreiben oder sogar übertragen.

In Android 4.3 und höher bietet SELinux eine obligatorische Zugriffssteuerung (MAC), die über herkömmlichen Umgebungen zur benutzerbestimmbaren Zugriffssteuerung (DAC) liegt. Software muss beispielsweise in der Regel als Root-Nutzerkonto ausgeführt werden, um auf Raw-Blockgeräte zu schreiben. Wenn in einer herkömmlichen DAC-basierten Linux-Umgebung der Root-Nutzer kompromittiert wird, kann dieser Nutzer auf jedes Raw-Blockgerät schreiben. SELinux kann jedoch verwendet werden, um diese Geräte zu kennzeichnen, sodass der Prozess, dem die Root-Berechtigung zugewiesen ist, nur auf die Geräte schreiben kann, die in der zugehörigen Richtlinie angegeben sind. Auf diese Weise kann der Prozess Daten und Systemeinstellungen außerhalb des spezifischen Raw-Blockgeräts nicht überschreiben.

Weitere Beispiele für Bedrohungen und Möglichkeiten, sie mit SELinux zu beheben, finden Sie unter Anwendungsfälle.

Maßnahmenebenen

SELinux kann in verschiedenen Modi implementiert werden:

  • Zulässig : Die SELinux-Sicherheitsrichtlinie wird nicht erzwungen, sondern nur protokolliert.
  • Erzwingen : Die Sicherheitsrichtlinie wird erzwungen und protokolliert. Fehler werden als EPERM-Fehler angezeigt.

Diese Auswahl ist binär und bestimmt, ob Ihre Richtlinie Maßnahmen ergreift oder Ihnen lediglich ermöglicht, potenzielle Fehler zu erfassen. Der Modus „Zulässig“ ist besonders bei der Implementierung nützlich.

Typen, Attribute und Regeln

Android verwendet die Type Enforcement (TE)-Komponente von SELinux für seine Richtlinie. Das bedeutet, dass alle Objekte (z. B. Datei, Prozess oder Socket) einen Typ haben. Standardmäßig hat eine App beispielsweise den Typ untrusted_app. Bei einem Prozess wird der Typ auch als Domain bezeichnet. Es ist möglich, einen Typ mit einem oder mehreren Attributen zu versehen. Attribute sind nützlich, um gleichzeitig auf mehrere Typen zu verweisen.

Objekte werden Klassen zugeordnet (z. B. eine Datei, ein Verzeichnis, ein symbolischer Link, ein Socket). Die verschiedenen Arten des Zugriffs für jede Klasse werden durch Berechtigungen dargestellt. Für die Klasse file gibt es beispielsweise die Berechtigung open. Während Typen und Attribute regelmäßig im Rahmen der Android-SELinux-Richtlinie aktualisiert werden, werden Berechtigungen und Klassen statisch definiert und selten im Rahmen einer neuen Linux-Version aktualisiert.

Eine Richtlinienregel hat die Form: allow source target:class permissions; wobei:

  • Source : Der Typ (oder das Attribut) des Subjekts der Regel. Wer fordert den Zugriff an?
  • Target : Der Typ (oder das Attribut) des Objekts. Auf was wird der Zugriff angefordert?
  • Class : Die Art des Objekts (z. B. Datei, Socket), auf das zugegriffen wird.
  • Berechtigungen – Der Vorgang (oder die Gruppe von Vorgängen) (z. B. Lesen, Schreiben), der ausgeführt wird.

Ein Beispiel für eine Regel ist:

allow untrusted_app app_data_file:file { read write };

Das bedeutet, dass Apps Dateien lesen und schreiben dürfen, die mit app_data_file gekennzeichnet sind. Es gibt andere Typen für Apps. isolated_app wird beispielsweise für App-Dienste mit isolatedProcess=true im Manifest verwendet. Anstatt die Regel für beide Typen zu wiederholen, verwendet Android ein Attribut namens appdomain für alle Typen, die Apps abdecken:

# Associate the attribute appdomain with the type untrusted_app.
typeattribute untrusted_app appdomain;

# Associate the attribute appdomain with the type isolated_app.
typeattribute isolated_app appdomain;

allow appdomain app_data_file:file { read write };

Wenn eine Regel geschrieben wird, die einen Attributnamen angibt, wird dieser Name automatisch auf die Liste der Domains oder Typen erweitert, die mit dem Attribut verknüpft sind. Einige wichtige Attribute sind:

  • domain : Attribut, das mit allen Prozesstypen verknüpft ist,
  • file_type : Attribut, das mit allen Dateitypen verknüpft ist.

Makros

Insbesondere für den Dateizugriff gibt es viele Arten von Berechtigungen. Die Berechtigung read reicht beispielsweise nicht aus, um die Datei zu öffnen oder stat aufzurufen. Um die Regeldefinition zu vereinfachen, bietet Android eine Reihe von Makros für die häufigsten Fälle. Um beispielsweise die fehlenden Berechtigungen wie open einzufügen, könnte die obige Regel so umgeschrieben werden:

allow appdomain app_data_file:file rw_file_perms;

Weitere Beispiele für nützliche Makros finden Sie in den global_macros und te_macros Dateien. Makros sollten nach Möglichkeit verwendet werden, um die Wahrscheinlichkeit von Fehlern aufgrund von Ablehnungen bei zugehörigen Berechtigungen zu verringern.

Sobald ein Typ definiert ist, muss er mit der Datei oder dem Prozess verknüpft werden, die er darstellt. Weitere Informationen dazu, wie diese Verknüpfung erfolgt, finden Sie unter SELinux implementieren. Weitere Informationen zu Regeln finden Sie im SELinux Notebook.

Sicherheitskontext und Kategorien

Beim Debuggen von SELinux-Richtlinien oder beim Kennzeichnen von Dateien (mit file_contexts oder ls -Z) stoßen Sie möglicherweise auf einen Sicherheitskontext (auch Label genannt). Beispiel: u:r:untrusted_app:s0:c15,c256,c513,c768. Ein Sicherheitskontext hat das Format user:role:type:sensitivity[:categories]. Die Felder user, role und sensitivity eines Kontexts können in der Regel ignoriert werden (siehe Spezifität). Das Feld type wird im vorherigen Abschnitt erläutert. categories sind Teil der Unterstützung für Multi-Level Security (MLS) in SELinux. In Android 12 und höher werden Kategorien für Folgendes verwendet:

  • App-Daten vor dem Zugriff durch eine andere App isolieren
  • App-Daten von einem physischen Nutzer zu einem anderen isolieren

Spezifität

Android verwendet nicht alle Funktionen von SELinux. Beachten Sie beim Lesen externer Dokumentation Folgendes:

  • Die meisten Richtlinien in AOSP werden mit der Kernel Policy Language definiert. Es gibt einige Ausnahmen für die Verwendung von Common Intermediate Language (CIL).
  • SELinux-Nutzer werden nicht verwendet. Der einzige definierte Nutzer ist u. Bei Bedarf werden physische Nutzer über das Feld „Kategorien“ eines Sicherheitskontexts dargestellt.
  • SELinux-Rollen und die rollenbasierte Zugriffssteuerung (Role-Based Access Control, RBAC) werden nicht verwendet. Es werden zwei Standardrollen definiert und verwendet: r für Subjekte und object_r für Objekte.
  • SELinux-Sensitivitäten werden nicht verwendet. Die Standardsensitivität s0 ist immer festgelegt.
  • SELinux-Booleans werden nicht verwendet. Wenn die Richtlinie für ein Gerät erstellt wird, hängt sie nicht vom Status des Geräts ab. Dies vereinfacht die Prüfung und das Debuggen von Richtlinien.