Diskretionäre Zugangskontrolle (DAC)

Dem Build hinzugefügte Dateisystemobjekte und -dienste benötigen häufig separate, eindeutige IDs, sogenannte Android-IDs (AIDs). Derzeit nutzen viele Ressourcen wie Dateien und Dienste unnötigerweise Kern-AIDs (von Android definiert). In vielen Fällen können Sie stattdessen OEM-AIDs (OEM-definiert) verwenden.

Frühere Versionen von Android (Android 7.x und niedriger) erweiterten den AIDs-Mechanismus mithilfe einer gerätespezifischen Datei android_filesystem_config.h , um Dateisystemfunktionen und/oder benutzerdefinierte OEM-AIDs anzugeben. Dieses System war jedoch nicht intuitiv, da es die Verwendung netter Namen für OEM-AIDs nicht unterstützte und Sie die rohen numerischen Werte für Benutzer- und Gruppenfelder angeben mussten, ohne dass es eine Möglichkeit gab, der numerischen AID einen benutzerfreundlichen Namen zuzuordnen.

Neuere Versionen von Android (Android 8.0 und höher) unterstützen eine neue Methode zur Erweiterung der Dateisystemfunktionen. Diese neue Methode unterstützt Folgendes:

  • Mehrere Quellspeicherorte für Konfigurationsdateien (ermöglicht erweiterbare Build-Konfigurationen).
  • Plausibilitätsprüfung der OEM-AID-Werte während der Erstellung.
  • Generierung eines benutzerdefinierten OEM-AID-Headers, der bei Bedarf in Quelldateien verwendet werden kann.
  • Zuordnung eines Anzeigenamens zum tatsächlichen OEM-AID-Wert. Unterstützt nicht-numerische Zeichenfolgenargumente für Benutzer und Gruppe, z. B. „foo“ anstelle von „2901“.

Zu den weiteren Verbesserungen gehört die Entfernung des android_ids[] -Arrays aus system/core/libcutils/include/private/android_filesystem_config.h . Dieses Array existiert jetzt in Bionic als vollständig privat generiertes Array mit Zugriffsmöglichkeiten über getpwnam() und getgrnam() . (Dies hat den Nebeneffekt, dass stabile Binärdateien erstellt werden, wenn Kern-AIDs geändert werden.) Tools und eine README-Datei mit weiteren Details finden Sie unter build/make/tools/fs_config .

Android-IDs (AIDs) hinzufügen

Android 8.0 hat das Array android_ids[] aus dem Android Open Source Project (AOSP) entfernt. Alle AID-freundlichen Namen werden stattdessen aus der Header-Datei system/core/libcutils/include/private/android_filesystem_config.h generiert, wenn das Bionic-Array android_ids[] generiert wird. Jede define , die mit AID_* übereinstimmt, wird vom Tool übernommen und * wird zum Namen in Kleinbuchstaben.

Zum Beispiel in private/android_filesystem_config.h :

#define AID_SYSTEM 1000

Wird:

  • Anzeigename: System
  • UID: 1000
  • GID: 1000

Um eine neue AOSP-Kern-AID hinzuzufügen, fügen Sie einfach #define zur Header-Datei android_filesystem_config.h hinzu. Die AID wird beim Build generiert und Schnittstellen zur Verfügung gestellt, die Benutzer- und Gruppenargumente verwenden. Das Tool bestätigt, dass das neue AID nicht im APP- oder OEM-Bereich liegt. Es berücksichtigt auch Änderungen an diesen Bereichen und sollte bei Änderungen oder neuen OEM-reservierten Bereichen automatisch neu konfiguriert werden.

AIDs konfigurieren

Um den neuen AIDs-Mechanismus zu aktivieren, legen Sie TARGET_FS_CONFIG_GEN in der Datei BoardConfig.mk fest. Diese Variable enthält eine Liste von Konfigurationsdateien, sodass Sie bei Bedarf Dateien anhängen können.

Konventionell verwenden Konfigurationsdateien den Namen config.fs , in der Praxis können Sie jedoch einen beliebigen Namen verwenden. config.fs Dateien liegen im Python-ConfigParser-INI-Format vor und enthalten einen Abschnitt „caps“ (zur Konfiguration von Dateisystemfunktionen) und einen Abschnitt „AIDs“ (zur Konfiguration von OEM-AIDs).

Konfigurieren des Caps-Bereichs

Der Abschnitt „caps“ unterstützt das Festlegen von Dateisystemfunktionen für Dateisystemobjekte innerhalb des Builds (das Dateisystem selbst muss diese Funktionalität ebenfalls unterstützen).

Da das Ausführen eines stabilen Dienstes als Root in Android zu einem CTS-Fehler (Compatibility Test Suite) führt, bestanden frühere Anforderungen zur Beibehaltung einer Funktion während der Ausführung eines Prozesses oder Dienstes darin, Funktionen einzurichten und dann setuid / setgid zu verwenden, um eine ordnungsgemäße AID auszuführen. Mit Caps können Sie diese Anforderungen überspringen und den Kernel dies für Sie erledigen lassen. Wenn die Kontrolle an main() übergeben wird, verfügt Ihr Prozess bereits über die erforderlichen Funktionen, sodass Ihr Dienst einen Nicht-Root-Benutzer und eine Nicht-Root-Gruppe verwenden kann (dies ist die bevorzugte Methode zum Starten privilegierter Dienste).

Der Abschnitt caps verwendet die folgende Syntax:

Abschnitt Wert Definition
[path] Der zu konfigurierende Dateisystempfad. Ein Pfad, der mit / endet, wird als Verzeichnis betrachtet, andernfalls handelt es sich um eine Datei.

Es ist ein Fehler, mehrere Abschnitte mit demselben [path] in verschiedenen Dateien anzugeben. In Python-Versionen <= 3.2 kann dieselbe Datei Abschnitte enthalten, die den vorherigen Abschnitt überschreiben; In Python 3.2 ist der strikte Modus eingestellt.
mode Oktaler Dateimodus Ein gültiger Oktaldateimodus mit mindestens 3 Ziffern. Wenn 3 angegeben ist, wird ihm eine 0 vorangestellt, andernfalls wird der Modus unverändert verwendet.
user AID_<Benutzer> Entweder die C- define für eine gültige AID oder der Anzeigename (z. B. sind sowohl AID_RADIO als auch radio akzeptabel). Informationen zum Definieren einer benutzerdefinierten AID finden Sie im Abschnitt „Konfigurieren der AID“ .
group AID_<Gruppe> Identisch mit Benutzer.
caps Deckel* Der Name wie in bionic/libc/kernel/uapi/linux/capability.h deklariert, ohne den führenden CAP_ . Gemischte Groß-/Kleinschreibung zulässig. Caps können auch roh sein:
  • binär (0b0101)
  • Oktal (0455)
  • int (42)
  • Hex (0xFF)
Trennen Sie mehrere Großbuchstaben durch Leerzeichen.

Ein Anwendungsbeispiel finden Sie unter Verwenden von Dateisystemfunktionen .

Konfigurieren des AID-Bereichs

Der AID-Abschnitt enthält OEM-AIDs und verwendet die folgende Syntax:

Abschnitt Wert Definition
[AID_<name>] Der <name> kann Zeichen in den festgelegten Großbuchstaben, Zahlen und Unterstrichen enthalten. Als Anzeigename wird die Kleinbuchstabenversion verwendet. Die generierte Header-Datei für die Code-Einbindung verwendet die genaue AID_<name> .

Es ist ein Fehler, mehrere Abschnitte mit demselben AID_<name> anzugeben (ohne Berücksichtigung der Groß- und Kleinschreibung mit denselben Einschränkungen wie [path] ).

<name> muss mit einem Partitionsnamen beginnen, um sicherzustellen, dass es nicht zu Konflikten mit verschiedenen Quellen kommt.
value <Nummer> Eine gültige Zahlenzeichenfolge im C-Stil (hex, oktal, binär und dezimal).

Es ist ein Fehler, mehrere Abschnitte mit derselben Wertoption anzugeben.

Wertoptionen müssen in dem Bereich angegeben werden, der der in <name> verwendeten Partition entspricht. Die Liste der gültigen Partitionen und ihrer entsprechenden Bereiche ist in system/core/libcutils/include/private/android_filesystem_config.h definiert. Die Optionen sind:
  • Anbieterpartition
    • AID_OEM_RESERVED_START(2900) - AID_OEM_RESERVED_END(2999)
    • AID_OEM_RESERVED_2_START(5000) - AID_OEM_RESERVED_2_END(5999)
  • Systempartition
    • AID_SYSTEM_RESERVED_START(6000) - AID_SYSTEM_RESERVED_END(6499)
  • ODM-Partition
    • AID_ODM_RESERVED_START(6500) - AID_ODM_RESERVED_END(6999)
  • Produktpartition
    • AID_PRODUCT_RESERVED_START(7000) - AID_PRODUCT_RESERVED_END(7499)
  • System_ext-Partition
    • AID_SYSTEM_EXT_RESERVED_START(7500) - AID_SYSTEM_EXT_RESERVED_END(7999)

Anwendungsbeispiele finden Sie unter Definieren von OEM-AID-Namen und Verwenden von OEM-AIDs .

Anwendungsbeispiele

In den folgenden Beispielen wird detailliert beschrieben, wie ein OEM-AID definiert und verwendet wird und wie Dateisystemfunktionen aktiviert werden. OEM-AID-Namen ( [AID_name ] ) müssen mit einem Partitionsnamen wie „ vendor_ “ beginnen, um sicherzustellen, dass sie nicht mit zukünftigen AOSP-Namen oder anderen Partitionen in Konflikt geraten.

Definieren von OEM-AID-Namen

Um eine OEM-AID zu definieren, erstellen Sie eine config.fs Datei und legen Sie den AID-Wert fest. Legen Sie beispielsweise in device/x/y/config.fs Folgendes fest:

[AID_VENDOR_FOO]
value: 2900

Legen Sie nach dem Erstellen der Datei die Variable TARGET_FS_CONFIG_GEN fest und verweisen Sie in BoardConfig.mk darauf. Legen Sie beispielsweise in device/x/y/BoardConfig.mk Folgendes fest:

TARGET_FS_CONFIG_GEN += device/x/y/config.fs

Ihr benutzerdefiniertes AID kann nun vom gesamten System bei einem neuen Build verwendet werden.

Verwendung von OEM-Hilfsmitteln

Um eine OEM-AID zu verwenden, fügen Sie in Ihrem C-Code die oemaids_headers in Ihr zugehöriges Makefile ein, fügen Sie #include "generated_oem_aid.h" hinzu und beginnen Sie dann mit der Verwendung der deklarierten Bezeichner. Fügen Sie beispielsweise in my_file.c Folgendes hinzu:

#include "generated_oem_aid.h"
…

If (ipc->uid == AID_VENDOR_FOO) {
  // Do something
...

Fügen Sie in Ihrer zugehörigen Android.bp Datei Folgendes hinzu:

header_libs: ["oemaids_headers"],

Wenn Sie eine Android.mk Datei verwenden, fügen Sie Folgendes hinzu:

LOCAL_HEADER_LIBRARIES := oemaids_headers

Verwendung freundlicher Namen

In Android 9 können Sie den Anzeigenamen für jede Schnittstelle verwenden, die AID-Namen unterstützt. Zum Beispiel:

  • In einem chown -Befehl in some/init.rc :
    chown vendor_foo /vendor/some/vendor_foo/file
    
  • In einem service in some/init.rc :
    service vendor_foo /vendor/bin/foo_service
        user vendor_foo
        group vendor_foo
    

Da die interne Zuordnung vom Anzeigenamen zur UID durch /vendor/etc/passwd und /vendor/etc/group erfolgt, muss die Vendor-Partition gemountet werden.

Verknüpfen von Anzeigenamen

Android 9 bietet Unterstützung für die Zuordnung eines Anzeigenamens zum tatsächlichen OEM-AID-Wert. Sie können nicht-numerische Zeichenfolgenargumente für Benutzer und Gruppe verwenden, z. B. „ vendor_foo “ anstelle von „2901“.

Konvertierung von AID in benutzerfreundliche Namen

Für OEM-AIDs erforderte Android 8.x die Verwendung von oem_#### mit getpwnam und ähnlichen Funktionen sowie an Stellen, die Suchvorgänge über getpwnam verarbeiten (z. B. init -Skripte). In Android 9 können Sie die Freunde getpwnam und getgrnam in Bionic zum Konvertieren von Android-IDs (AIDs) in benutzerfreundliche Namen und umgekehrt verwenden.

Nutzung von Dateisystemfunktionen

Um Dateisystemfunktionen zu aktivieren, erstellen Sie einen caps-Abschnitt in der Datei config.fs . Fügen Sie beispielsweise in device/x/y/config.fs den folgenden Abschnitt hinzu:

[system/bin/foo_service]
mode: 0555
user: AID_VENDOR_FOO
group: AID_SYSTEM
caps: SYS_ADMIN | SYS_NICE

Stellen Sie nach dem Erstellen der Datei TARGET_FS_CONFIG_GEN so ein, dass es auf diese Datei in BoardConfig.mk verweist. Legen Sie beispielsweise in device/x/y/BoardConfig.mk Folgendes fest:

TARGET_FS_CONFIG_GEN += device/x/y/config.fs

Wenn der Dienst vendor_ foo ausgeführt wird, startet er mit den Funktionen CAP_SYS_ADMIN und CAP_SYS_NICE ohne setuid und setgid -Aufrufe. Darüber hinaus benötigt die SELinux-Richtlinie des vendor_ foo -Dienstes nicht mehr die Funktionen setuid und setgid und kann gelöscht werden.

Außerkraftsetzungen konfigurieren (Android 6.x-7.x)

Android 6.0 hat fs_config und zugehörige Strukturdefinitionen ( system/core/include/private/android_filesystem_config.h ) nach system/core/libcutils/fs_config.c verschoben, wo sie durch Binärdateien, die in /system/etc/fs_config_dirs und installiert sind, aktualisiert oder überschrieben werden können /system/etc/fs_config_files . Durch die Verwendung separater Abgleichs- und Analyseregeln für Verzeichnisse und Dateien (die zusätzliche Glob-Ausdrücke verwenden könnten) konnte Android Verzeichnisse und Dateien in zwei verschiedenen Tabellen verarbeiten. Strukturdefinitionen in system/core/libcutils/fs_config.c ermöglichten nicht nur das Lesen von Verzeichnissen und Dateien zur Laufzeit, sondern der Host konnte während der Erstellungszeit auch dieselben Dateien verwenden, um Dateisystem-Images wie ${OUT}/system/etc/fs_config_dirs und ${OUT}/system/etc/fs_config_files zu erstellen ${OUT}/system/etc/fs_config_files .

Obwohl die Override-Methode zum Erweitern des Dateisystems durch das in Android 8.0 eingeführte modulare Konfigurationssystem ersetzt wurde, können Sie bei Bedarf weiterhin die alte Methode verwenden. In den folgenden Abschnitten wird detailliert beschrieben, wie Sie Override-Dateien generieren und einschließen und das Dateisystem konfigurieren.

Generieren von Override-Dateien

Sie können die ausgerichteten Binärdateien /system/etc/fs_config_dirs und /system/etc/fs_config_files mit dem Tool fs_config_generate in build/tools/fs_config generieren. Das Tool verwendet eine libcutils Bibliotheksfunktion ( fs_config_generate() ), um DAC-Anforderungen in einem Puffer zu verwalten und definiert Regeln für eine Include-Datei, um die DAC-Regeln zu institutionalisieren.

Erstellen Sie zur Verwendung eine Include-Datei in device/ vendor / device /android_filesystem_config.h , die als Überschreibung fungiert. Die Datei muss das in system/core/include/private/android_filesystem_config.h definierte structure fs_path_config mit den folgenden Strukturinitialisierungen für Verzeichnis- und Dateisymbole verwenden:

  • Verwenden Sie für Verzeichnisse android _device _dirs[] .
  • Verwenden Sie für Dateien android _device _files[] .

Wenn Sie android_device_dirs[] und android_device_files[] nicht verwenden, können Sie NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS und NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES definieren (siehe Beispiel unten). Sie können die Überschreibungsdatei auch mit TARGET_ANDROID_FILESYSTEM_CONFIG_H in der Board-Konfiguration angeben, mit einem erzwungenen Basisnamen von android_filesystem_config.h .

Einschließlich Override-Dateien

Um Dateien einzuschließen, stellen Sie sicher, dass PRODUCT_PACKAGES fs_config_dirs und/oder fs_config_files enthält, damit sie in /system/etc/fs_config_dirs bzw. /system/etc/fs_config_files installiert werden können. Das Build-System sucht nach der benutzerdefinierten android_filesystem_config.h in $(TARGET_DEVICE_DIR) , wo BoardConfig.mk vorhanden ist. Wenn diese Datei an anderer Stelle vorhanden ist, legen Sie die Board-Konfigurationsvariable TARGET_ANDROID_FILESYSTEM_CONFIG_H so fest, dass sie auf diesen Speicherort verweist.

Konfigurieren des Dateisystems

So konfigurieren Sie das Dateisystem in Android 6.0 und höher:

  1. Erstellen Sie die Datei $(TARGET_DEVICE_DIR)/android_filesystem_config.h .
  2. Fügen Sie die fs_config_dirs und/oder fs_config_files zu PRODUCT_PACKAGES in der Board-Konfigurationsdatei hinzu (z. B. $(TARGET_DEVICE_DIR)/device.mk ).

Beispiel zum Überschreiben

Dieses Beispiel zeigt einen Patch zum Überschreiben des Daemons system/bin/glgps , um Wake-Lock-Unterstützung im Verzeichnis device/ vendor / device hinzuzufügen. Beachten Sie Folgendes:

  • Jeder Struktureintrag besteht aus Modus, UID, GID, Funktionen und dem Namen. system/core/include/private/android_filesystem_config.h wird automatisch eingebunden, um das Manifest #defines ( AID_ROOT , AID_SHELL , CAP_BLOCK_SUSPEND ) bereitzustellen.
  • Der Abschnitt android_device_files[] enthält eine Aktion, um den Zugriff auf system/etc/fs_config_dirs zu unterdrücken, wenn dieser nicht angegeben ist. Dies dient als zusätzlicher DAC-Schutz bei fehlendem Inhalt für Verzeichnisüberschreibungen. Dies ist jedoch ein schwacher Schutz; Wenn jemand die Kontrolle über /system hat, kann er normalerweise alles tun, was er will.
diff --git a/android_filesystem_config.h b/android_filesystem_config.h
new file mode 100644
index 0000000..874195f
--- /dev/null
+++ b/android_filesystem_config.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+/* This file is used to define the properties of the filesystem
+** images generated by build tools (eg: mkbootfs) and
+** by the device side of adb.
+*/
+
+#define NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
+/* static const struct fs_path_config android_device_dirs[] = { }; */
+
+/* Rules for files.
+** These rules are applied based on "first match", so they
+** should start with the most specific path and work their
+** way up to the root. Prefixes ending in * denotes wildcard
+** and will allow partial matches.
+*/
+static const struct fs_path_config android_device_files[] = {
+  { 00755, AID_ROOT, AID_SHELL, (1ULL << CAP_BLOCK_SUSPEND),
"system/bin/glgps" },
+#ifdef NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
+  { 00000, AID_ROOT, AID_ROOT, 0, "system/etc/fs_config_dirs" },
+#endif
+};


diff --git a/device.mk b/device.mk
index 0c71d21..235c1a7 100644
--- a/device.mk
+++ b/device.mk
@@ -18,7 +18,8 @@ PRODUCT_PACKAGES := \
     libwpa_client \
     hostapd \
     wpa_supplicant \
-    wpa_supplicant.conf
+    wpa_supplicant.conf \
+    fs_config_files

 ifeq ($(TARGET_PREBUILT_KERNEL),)
 ifeq ($(USE_SVELTE_KERNEL), true)

Migration von Dateisystemen aus früheren Versionen

Beachten Sie bei der Migration von Dateisystemen von Android 5.x und früher, dass Android 6.x

  • Entfernt einige Includes, Strukturen und Inline-Definitionen.
  • Erfordert einen Verweis auf libcutils , anstatt direkt von system/core/include/private/android_filesystem_config.h ausgeführt zu werden. Private ausführbare Dateien des Geräteherstellers, die von system/code/include/private_filesystem_config.h für die Datei- oder Verzeichnisstrukturen oder fs_config abhängen, müssen libcutils Bibliotheksabhängigkeiten hinzufügen.
  • Erfordert private Zweigkopien des Geräteherstellers von system/core/include/private/android_filesystem_config.h mit zusätzlichem Inhalt auf vorhandenen Zielen, um nach device/ vendor / device /android_filesystem_config.h zu verschieben.
  • Behält sich das Recht vor, SELinux Mandatory Access Controls (MAC) auf Konfigurationsdateien auf dem Zielsystem anzuwenden. Implementierungen, die benutzerdefinierte ausführbare Zieldateien mit fs_config() enthalten, müssen den Zugriff sicherstellen.