Dem Build hinzugefügte Dateisystemobjekte und -dienste benötigen häufig separate, eindeutige IDs, die als Android-IDs (AIDs) bekannt sind. Derzeit verwenden viele Ressourcen wie Dateien und Dienste unnötig Kern- (Android-definierte) AIDs; In vielen Fällen können Sie stattdessen OEM (OEM-definierte) AIDs verwenden.
Frühere Versionen von Android (Android 7.x und niedriger) erweiterten den AIDs-Mechanismus mithilfe einer gerätespezifischen android_filesystem_config.h
-Datei, um Dateisystemfunktionen und/oder benutzerdefinierte OEM-AIDs anzugeben. Dieses System war jedoch nicht intuitiv, da es die Verwendung schöner Namen für OEM-AIDs nicht unterstützte, sodass Sie die rohen Zahlen für Benutzer- und Gruppenfelder angeben mussten, ohne einen Anzeigenamen mit der numerischen AID zu verknüpfen.
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 von OEM-AID-Werten während der Bauzeit.
- 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 String-Argumente für Benutzer und Gruppe, zB "foo" statt "2901".
Zu den weiteren Verbesserungen gehört das Entfernen 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 Zugriffsmethoden über getpwnam()
und getgrnam()
. (Dies hat den Nebeneffekt, dass stabile Binärdateien erzeugt werden, wenn Kern-AIDs modifiziert werden.) Tools und eine README-Datei mit weiteren Details finden Sie unter build/make/tools/fs_config
.
Hinzufügen von Android-IDs (AIDs)
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
, wenn das Bionic android_ids[]
Array generiert wird. Jede define
, die mit AID_*
übereinstimmt, wird vom Werkzeug aufgenommen und * wird zum kleingeschriebenen Namen.
Zum Beispiel in private/android_filesystem_config.h
:
#define AID_SYSTEM 1000
Wird:
- Anzeigename: System
- UID: 1000
- gid: 1000
Um eine neue AOSP-Core-AID hinzuzufügen, fügen Sie einfach #define
zur Header-Datei android_filesystem_config.h
. Die AID wird beim Build generiert und Schnittstellen zur Verfügung gestellt, die Benutzer- und Gruppenargumente verwenden. Das Werkzeug validiert, dass das neue AID nicht innerhalb der APP- oder OEM-Bereiche liegt; Es respektiert 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, setzen TARGET_FS_CONFIG_GEN
in der Datei BoardConfig.mk
. Diese Variable enthält eine Liste von Konfigurationsdateien, sodass Sie Dateien nach Bedarf anhängen können.
Standardmäßig verwenden Konfigurationsdateien den Namen config.fs
, aber in der Praxis können Sie jeden beliebigen Namen verwenden. config.fs
Dateien sind im Python-ConfigParser-INI-Format und enthalten einen Caps-Abschnitt (zum Konfigurieren von Dateisystemfunktionen) und einen AIDs-Abschnitt (zum Konfigurieren 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 einen CTS-Fehler (Compatibility Test Suite) verursacht, umfassten frühere Anforderungen zum Beibehalten einer Funktion während der Ausführung eines Prozesses oder Dienstes das Einrichten von Funktionen und die Verwendung von setuid
/ setgid
für eine ordnungsgemäße Ausführung von AID. Mit Caps können Sie diese Anforderungen überspringen und den Kernel für Sie erledigen lassen. Wenn die Kontrolle an main()
übergeben wird, verfügt Ihr Prozess bereits über die Fähigkeiten, die er benötigt, damit Ihr Dienst einen Nicht-Root-Benutzer und eine Gruppe verwenden kann (dies ist die bevorzugte Methode zum Starten privilegierter Dienste).
Der Großbuchstabenabschnitt verwendet die folgende Syntax:
Abschnitt | Wert | Definition |
---|---|---|
[path] | Der zu konfigurierende Dateisystempfad. Ein Pfad, der mit / endet, wird als Verzeichnis betrachtet, ansonsten ist es 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 es auf den strikten Modus eingestellt. | |
mode | Oktaler Dateimodus | Ein gültiger oktaler Dateimodus mit mindestens 3 Ziffern. Wenn 3 angegeben ist, wird ihr 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 freundliche Name (z. B. sind sowohl AID_RADIO als auch radio zulässig). Informationen zum Definieren einer benutzerdefinierten AID finden Sie im Abschnitt Konfigurieren der AID . |
group | AID_<Gruppe> | Gleich wie Benutzer. |
caps | Deckel* | Der Name, wie er in bionic/libc/kernel/uapi/linux/capability.h ohne das führende CAP_ . Mischfall erlaubt. Caps können auch roh sein:
|
Ein Verwendungsbeispiel finden Sie unter Dateisystemfunktionen verwenden .
Konfigurieren des AID-Bereichs
Der Abschnitt AID enthält OEM-AIDs und verwendet die folgende Syntax:
Abschnitt | Wert | Definition |
---|---|---|
[AID_<name>] | Der <name> kann Zeichen in Großbuchstaben, Ziffern und Unterstriche enthalten. Als Anzeigename wird die Kleinbuchstabenversion verwendet. Die generierte Header-Datei für die Code-Einbindung verwendet die exakte AID_<name> .Es ist ein Fehler, mehrere Abschnitte mit demselben AID_<name> anzugeben (Groß-/Kleinschreibung wird nicht beachtet, mit denselben Einschränkungen wie [path] ).<name> muss mit einem Partitionsnamen beginnen, um sicherzustellen, dass es nicht zu Konflikten mit anderen 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 . Die Optionen sind:
|
Anwendungsbeispiele finden Sie unter OEM-AID-Namen definieren und OEM-AIDs verwenden .
Anwendungsbeispiele
In den folgenden Beispielen wird detailliert beschrieben, wie eine 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
und zeigen 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
Ihre benutzerdefinierte AID kann jetzt vom gesamten System in einem neuen Build verwendet werden.
Verwendung von OEM-AIDs
Um eine OEM-AID zu verwenden, fügen Sie in Ihrem C-Code die oemaids_headers
in Ihr zugehöriges Makefile ein und 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
Verwenden von freundlichen 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 insome/init.rc
:chown vendor_foo /vendor/some/vendor_foo/file
- In einem
service
insome/init.rc
:service vendor_foo /vendor/bin/foo_service user vendor_foo group vendor_foo
Da die interne Zuordnung vom Anzeigenamen zur UID von /vendor/etc/passwd
und /vendor/etc/group
durchgeführt wird, muss die Herstellerpartition eingehängt werden.
Zuordnen von Anzeigenamen
Android 9 bietet Unterstützung für die Zuordnung eines Anzeigenamens zum tatsächlichen OEM-AID-Wert. Sie können nicht-numerische String-Argumente für Benutzer und Gruppe verwenden, dh " vendor_foo " anstelle von "2901".
Konvertieren von AID in freundliche Namen
Für OEM-AIDs erforderte Android 8.x die Verwendung von oem_####
mit getpwnam
und ähnlichen Funktionen sowie an Stellen, die Lookups über getpwnam
handhaben (z. B. init
-Skripte). In Android 9 können Sie die getpwnam
und getgrnam
Freunde in Bionic verwenden, um Android-IDs (AIDs) in Anzeigenamen umzuwandeln und umgekehrt.
Verwenden von Dateisystemfunktionen
Um die 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
Nachdem Sie die Datei erstellt haben, legen TARGET_FS_CONFIG_GEN
so fest, dass es auf diese Datei in BoardConfig.mk
zeigt. 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 Capabilities CAP_SYS_ADMIN
und CAP_SYS_NICE
ohne setuid
und setgid
-Aufrufe. Darüber hinaus setgid
die SELinux-Richtlinie des Anbieter_foo-Dienstes nicht mehr die Fähigkeiten setuid
und vendor_ foo
und kann gelöscht werden.
Außerkraftsetzungen konfigurieren (Android 6.x-7.x)
Android 6.0 fs_config
und zugehörige Strukturdefinitionen ( system/core/include/private/android_filesystem_config.h
) nach system/core/libcutils/fs_config.c
wo sie aktualisiert oder durch in /system/etc/fs_config_dirs
installierte Binärdateien überschrieben werden konnten /system/etc/fs_config_files
. Durch die Verwendung separater Abgleichs- und Parsing-Regeln 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 dieselben Dateien verwenden, um Dateisystem-Images als ${OUT}/system/etc/fs_config_dirs
und ${OUT}/system/etc/fs_config_files
zu erstellen ${OUT}/system/etc/fs_config_files
.
Während 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 beschrieben, wie Sie Überschreibungsdateien 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
. 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 Override fungiert. Die Datei muss das in system/core/include/private/android_filesystem_config.h
definierte structure fs_path_config
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 android_device_dirs[]
und android_device_files[]
nicht verwendet werden, können Sie NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
und NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES
definieren (siehe Beispiel unten). Sie können die Override-Datei 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
Stellen Sie zum Einschließen von Dateien sicher, dass PRODUCT_PACKAGES
fs_config_dirs
und/oder fs_config_files
, damit es sie in /system/etc/fs_config_dirs
bzw. /system/etc/fs_config_files
kann. Das Build-System sucht nach benutzerdefinierter android_filesystem_config.h
in $(TARGET_DEVICE_DIR)
, wo BoardConfig.mk
vorhanden ist. Wenn diese Datei an anderer Stelle existiert, setzen Sie die Board-Konfigurationsvariable TARGET_ANDROID_FILESYSTEM_CONFIG_H
so, dass sie auf diesen Ort zeigt.
Konfigurieren des Dateisystems
So konfigurieren Sie das Dateisystem in Android 6.0 und höher:
- Erstellen Sie die Datei
$(TARGET_DEVICE_DIR)/android_filesystem_config.h
. - Fügen Sie die
fs_config_dirs
und/oderfs_config_files
zuPRODUCT_PACKAGES
in der Board-Konfigurationsdatei hinzu (z. B.$(TARGET_DEVICE_DIR)/device.mk
).
Beispiel überschreiben
Dieses Beispiel zeigt einen Patch zum Überschreiben des Daemons system/bin/glgps
, um Wakelock-Unterstützung im Verzeichnis device/ vendor / device
hinzuzufügen. Beachten Sie Folgendes:
- Jeder Struktureintrag ist der Modus, die UID, die GID, die Fähigkeiten und der Name.
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 zum Unterdrücken des Zugriffs aufsystem/etc/fs_config_dirs
, wenn nicht angegeben, was als zusätzlicher DAC-Schutz bei fehlendem Inhalt für Verzeichnisüberschreibungen dient. 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)
Migrieren von Dateisystemen aus früheren Versionen
Beachten Sie beim Migrieren 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 vonsystem/core/include/private/android_filesystem_config.h
. Private ausführbare Dateien des Geräteherstellers, die vonsystem/code/include/private_filesystem_config.h
für die Datei- oder Verzeichnisstrukturen oderfs_config
, müssenlibcutils
Bibliotheksabhängigkeiten hinzufügen. - Erfordert private Branch-Kopien des Geräteherstellers von
system/core/include/private/android_filesystem_config.h
mit zusätzlichem Inhalt auf vorhandenen Zielen, um nachdevice/ vendor / device /android_filesystem_config.h
. - 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()
, müssen den Zugriff sicherstellen.