Obiekty i usługi systemu plików dodawane do kompilacji często wymagają oddzielnych, unikalnych identyfikatorów, zwanych identyfikatorami Androida (AID). Obecnie wiele zasobów, takich jak pliki i usługi, niepotrzebnie używa podstawowych identyfikatorów AID (zdefiniowanych przez Androida). W wielu przypadkach możesz zamiast nich używać identyfikatorów AID OEM (zdefiniowanych przez producenta OEM).
Wcześniejsze wersje Androida (Android 7.x i starsze) rozszerzały mechanizm identyfikatorów AID
za pomocą pliku android_filesystem_config.h
specyficznego dla urządzenia, aby określić możliwości systemu plików lub niestandardowe identyfikatory AID OEM. Ten
system był jednak mało intuicyjny, ponieważ nie obsługiwał używania przyjaznych nazw identyfikatorów AID OEM.
Wymagał podania surowej wartości liczbowej w polach użytkownika i grupy bez
możliwości powiązania przyjaznej nazwy z numerycznym identyfikatorem AID.
Nowsze wersje Androida (Android 8.0 i nowsze) obsługują nową metodę rozszerzania możliwości systemu plików. Ta nowa metoda obsługuje te funkcje:
- Wiele lokalizacji źródłowych plików konfiguracji (umożliwia rozszerzalne konfiguracje kompilacji).
- Sprawdzanie poprawności wartości identyfikatorów AID OEM podczas kompilacji.
- Generowanie niestandardowego nagłówka identyfikatora AID OEM, którego można używać w plikach źródłowych w razie potrzeby.
- Powiązanie przyjaznej nazwy z rzeczywistą wartością identyfikatora AID OEM. Obsługuje argumenty ciągów nienumerycznych dla użytkownika i grupy, np. "foo" zamiast "2901".
Dodatkowe ulepszenia obejmują usunięcie tablicy android_ids[]
z
system/core/libcutils/include/private/android_filesystem_config.h. Ta
tablica znajduje się teraz w Bionic jako w pełni prywatna wygenerowana tablica z
akcesorami getpwnam() i getgrnam(). (Ma to dodatkowy efekt w postaci stabilnych plików binarnych, ponieważ podstawowe identyfikatory AID są modyfikowane). Więcej informacji o
narzędziach i pliku README znajdziesz w
build/make/tools/fs_config.
Dodawanie identyfikatorów Androida (AID)
W Androidzie 8.0 usunięto tablicę android_ids[] z projektu Android
Open Source Project (AOSP). Wszystkie przyjazne nazwy identyfikatorów AID są generowane z
pliku nagłówkowego system/core/libcutils/include/private/android_filesystem_config.h
podczas generowania tablicy android_ids[] w Bionic. Każdy
define pasujący do AID_* jest wykrywany przez narzędzie
a * staje się nazwą w małych literach.
Na przykład w private/android_filesystem_config.h:
#define AID_SYSTEM 1000Staje się:
- Przyjazna nazwa: system
- uid: 1000
- gid: 1000
Aby dodać nowy podstawowy identyfikator AID AOSP, po prostu dodaj #define do
android_filesystem_config.h pliku nagłówkowego. Identyfikator AID jest
generowany podczas kompilacji i udostępniany interfejsom, które używają argumentów użytkownika i grupy. Narzędzie sprawdza, czy nowy identyfikator AID nie znajduje się w zakresach aplikacji ani OEM
. Uwzględnia też zmiany w tych zakresach i powinno automatycznie
skonfigurować się ponownie w przypadku zmian lub nowych zakresów zarezerwowanych przez OEM.
Konfigurowanie identyfikatorów AID
Aby włączyć nowy mechanizm identyfikatorów AID, ustaw TARGET_FS_CONFIG_GEN w pliku
BoardConfig.mk. Ta zmienna zawiera listę plików konfiguracji, dzięki czemu możesz dodawać pliki w razie potrzeby.
Zgodnie z konwencją pliki konfiguracji używają nazwy config.fs, ale w
praktyce możesz użyć dowolnej nazwy. config.fs pliki są w formacie
Python
ConfigParser ini i zawierają sekcję caps (do konfigurowania możliwości systemu
plików) oraz sekcję AIDs (do konfigurowania identyfikatorów AID OEM).
Konfigurowanie sekcji caps
Sekcja caps obsługuje ustawianie możliwości systemu plików w obiektach systemu plików w kompilacji (sam system plików musi też obsługiwać tę funkcję).
Ponieważ uruchamianie stabilnej usługi jako root w Androidzie powoduje
niepowodzenie testu Compatibility Test Suite (CTS)
, poprzednie wymagania dotyczące zachowania możliwości podczas uruchamiania
procesu lub usługi obejmowały skonfigurowanie możliwości, a następnie użycie
setuid/setgid do odpowiedniego identyfikatora AID. Dzięki możliwościom możesz pominąć te wymagania i pozwolić jądru na wykonanie tych czynności. Gdy sterowanie zostanie
przekazane do main(), Twój proces będzie już miał potrzebne możliwości, dzięki czemu usługa będzie mogła używać użytkownika i grupy innych niż root (jest to preferowany
sposób uruchamiania usług z uprawnieniami).
Sekcja caps używa tej składni:
| Sekcja | Wartość | Definicja |
|---|---|---|
[path] |
Ścieżka systemu plików do skonfigurowania. Ścieżka kończąca się znakiem / jest traktowana jako katalog,
w przeciwnym razie jest to plik.
Określenie w różnych plikach wielu sekcji z tą samą wartością [path] jest błędem. W Pythonie w wersji <= 3.2 ten
sam plik może zawierać sekcje, które zastępują poprzednią sekcję. W Pythonie
3.2 jest ustawiony tryb ścisły. |
|
mode |
Ósemkowy tryb pliku | Prawidłowy ósemkowy tryb pliku składający się z co najmniej 3 cyfr. Jeśli określono 3, jest on poprzedzony cyfrą 0, w przeciwnym razie tryb jest używany w takiej postaci. |
user |
AID_<user> | Albo C define dla prawidłowego identyfikatora AID, albo przyjazna nazwa
(np. akceptowane są zarówno AID_RADIO, jak i radio). Aby
zdefiniować niestandardowy identyfikator AID, przeczytaj sekcję Konfigurowanie
sekcji AID. |
group |
AID_<group> | Tak samo jak w przypadku użytkownika. |
caps |
cap* | Nazwa zadeklarowana w
bionic/libc/kernel/uapi/linux/capability.h
bez początkowego CAP_. Dozwolone są wielkie i małe litery. Możliwości mogą też być
surowe:
|
Przykład użycia znajdziesz w artykule Korzystanie z możliwości systemu plików.
Konfigurowanie sekcji AID
Sekcja AID zawiera identyfikatory AID OEM i używa tej składni:
| Sekcja | Wartość | Definicja |
|---|---|---|
[AID_<name>] |
<name> może zawierać znaki z zestawu:
wielkie litery, cyfry i podkreślenia. Jako przyjazna nazwa jest używana wersja w małych literach. Wygenerowany plik nagłówkowy do włączenia kodu używa dokładnie
AID_<name>.
Określenie w różnych plikach wielu sekcji z tą samą wartością AID_<name> (bez uwzględniania wielkości liter i z tymi samymi ograniczeniami co
[path]) jest błędem.
<name> musi zaczynać się od nazwy partycji, aby uniknąć konfliktu z różnymi źródłami. |
|
value |
<number> | Prawidłowy ciąg znaków liczbowych w stylu C (szesnastkowy, ósemkowy, binarny i dziesiętny).
Określenie w różnych plikach wielu sekcji z tą samą opcją value jest błędem. Opcje value muszą być określone w zakresie odpowiadającym partycji używanej w <name>. Lista prawidłowych partycji i odpowiadających im
zakresów jest zdefiniowana w system/core/libcutils/include/private/android_filesystem_config.h.
Dostępne opcje:
|
Przykłady użycia znajdziesz w artykułach Definiowanie identyfikatorów AID OEM i Korzystanie z identyfikatorów AID OEM.
Przykłady użycia
Poniższe przykłady pokazują, jak zdefiniować i używać identyfikatora AID OEM oraz jak włączyć możliwości systemu plików. Nazwy identyfikatorów AID OEM ([AID_name]) muszą zaczynać się od nazwy partycji, np. „vendor_”, aby nie powodować konfliktu z przyszłymi nazwami AOSP ani innymi partycjami.
Definiowanie nazw identyfikatorów AID OEM
Aby zdefiniować identyfikator AID OEM, utwórz plik config.fs i ustaw
wartość identyfikatora AID. Na przykład w device/x/y/config.fs ustaw te
wartości:
[AID_VENDOR_FOO] value: 2900
Po utworzeniu pliku ustaw zmienną TARGET_FS_CONFIG_GEN
i wskaż ją w BoardConfig.mk. Na przykład w
device/x/y/BoardConfig.mk ustaw te wartości:
TARGET_FS_CONFIG_GEN += device/x/y/config.fs
Twój niestandardowy identyfikator AID może być teraz używany przez system w nowej kompilacji.
Korzystanie z identyfikatorów AID OEM
Aby użyć identyfikatora AID OEM, w kodzie C uwzględnij oemaids_headers w powiązanym
pliku Makefile i dodaj #include "generated_oem_aid.h", a następnie zacznij używać zadeklarowanych
identyfikatorów. Na przykład w my_file.c dodaj te wartości:
#include "generated_oem_aid.h" … If (ipc->uid == AID_VENDOR_FOO) { // Do something ...
W powiązanym pliku Android.bp dodaj te wartości:
header_libs: ["oemaids_headers"],
Jeśli używasz pliku Android.mk, dodaj te wartości:
LOCAL_HEADER_LIBRARIES := oemaids_headers
Korzystanie z przyjaznych nazw
W Androidzie 9 możesz używać przyjaznej nazwy w przypadku każdego interfejsu, który obsługuje nazwy identyfikatorów AID. Przykład:
- W poleceniu
chownwsome/init.rc:chown vendor_foo /vendor/some/vendor_foo/file
- W
servicewsome/init.rc:service vendor_foo /vendor/bin/foo_service user vendor_foo group vendor_foo
Ponieważ wewnętrzne mapowanie z przyjaznej nazwy na uid jest wykonywane przez
/vendor/etc/passwd i /vendor/etc/group, partycja dostawcy
musi być zamontowana.
Powiązywanie przyjaznych nazw
Android 9 obsługuje powiązywanie przyjaznej nazwy z rzeczywistą wartością identyfikatora AID OEM. Możesz używać argumentów ciągów nienumerycznych dla użytkownika i grupy, czyli "vendor_foo" zamiast "2901".
Konwertowanie identyfikatorów AID na przyjazne nazwy
W przypadku
identyfikatorów AID OEM Android 8.x wymagał używania
oem_#### z getpwnam i podobnymi funkcjami, a
także w miejscach, które obsługują wyszukiwanie za pomocą getpwnam (np.
init skrypty). W Androidzie 9 możesz
używać funkcji getpwnam i getgrnam w Bionic do
konwertowania identyfikatorów Androida (AID) na przyjazne nazwy i odwrotnie.
Korzystanie z możliwości systemu plików
Aby włączyć możliwości systemu plików, utwórz sekcję caps w pliku
config.fs. Na przykład w
device/x/y/config.fs dodaj tę sekcję:
[system/bin/foo_service] mode: 0555 user: AID_VENDOR_FOO group: AID_SYSTEM caps: SYS_ADMIN | SYS_NICE
Po utworzeniu pliku ustaw TARGET_FS_CONFIG_GEN tak, aby wskazywał
ten plik w BoardConfig.mk. Na przykład w
device/x/y/BoardConfig.mk ustaw te wartości:
TARGET_FS_CONFIG_GEN += device/x/y/config.fs
Gdy usługa vendor_foo jest wykonywana, zaczyna się
od możliwości CAP_SYS_ADMIN i CAP_SYS_NICE
bez wywołań setuid i setgid. Ponadto zasady SELinux usługi
vendor_foo nie wymagają już możliwości setuid i setgid i można je
usunąć.
Konfigurowanie zastąpień (Android 6.x–7.x)
W Androidzie 6.0 przeniesiono fs_config i powiązane definicje struktury (system/core/include/private/android_filesystem_config.h) do system/core/libcutils/fs_config.c, gdzie można je aktualizować lub zastępować plikami binarnymi zainstalowanymi w /system/etc/fs_config_dirs i /system/etc/fs_config_files. Używanie oddzielnych reguł dopasowywania i analizowania
dla katalogów i plików (które mogą używać dodatkowych wyrażeń glob)
umożliwiło Androidowi obsługę katalogów i plików w 2 różnych tabelach.
Definicje struktury w system/core/libcutils/fs_config.c umożliwiały nie
tylko odczytywanie katalogów i plików w czasie działania, ale też host mógł używać
tych samych plików podczas kompilacji do tworzenia obrazów systemu plików jako
${OUT}/system/etc/fs_config_dirs i
${OUT}/system/etc/fs_config_files.
Metoda zastępowania rozszerzania systemu plików została zastąpiona przez modułowy system konfiguracji wprowadzony w Androidzie 8.0, ale w razie potrzeby możesz nadal używać starej metody. W kolejnych sekcjach opisujemy, jak generować i uwzględniać pliki zastępowania oraz jak konfigurować system plików.
Generowanie plików zastępowania
Wyrównane pliki binarne /system/etc/fs_config_dirs i /system/etc/fs_config_files możesz wygenerować za pomocą narzędzia fs_config_generate w build/tools/fs_config. Narzędzie używa funkcji biblioteki libcutils (fs_config_generate()) do zarządzania wymaganiami DAC w buforze i definiuje reguły dla pliku dołączanego, aby zinstytucjonalizować reguły DAC.
Aby użyć, utwórz plik dołączany w
device/vendor/device/android_filesystem_config.h
, który będzie działać jako zastąpienie. Plik musi używać formatu structure fs_path_config zdefiniowanego w system/core/include/private/android_filesystem_config.h z tymi inicjalizacjami struktury dla symboli katalogów i plików:
- W przypadku katalogów użyj
android_device_dirs[]. - W przypadku plików użyj
android_device_files[].
Jeśli nie używasz android_device_dirs[] i
android_device_files[], możesz zdefiniować
NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS i
NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES (zobacz
przykład poniżej). Możesz też określić plik zastępowania za pomocą TARGET_ANDROID_FILESYSTEM_CONFIG_H w konfiguracji płyty, z wymuszoną nazwą podstawową android_filesystem_config.h.
Uwzględnianie plików zastępowania
Aby uwzględnić pliki, upewnij się, że PRODUCT_PACKAGES zawiera
fs_config_dirs lub fs_config_files, aby można było je
zainstalować odpowiednio w /system/etc/fs_config_dirs i
/system/etc/fs_config_files. System kompilacji
szuka niestandardowego pliku android_filesystem_config.h w
$(TARGET_DEVICE_DIR), gdzie znajduje się BoardConfig.mk.
Jeśli ten plik znajduje się w innym miejscu, ustaw zmienną konfiguracji płyty
TARGET_ANDROID_FILESYSTEM_CONFIG_H tak, aby wskazywała tę lokalizację.
Konfigurowanie systemu plików
Aby skonfigurować system plików w Androidzie 6.0 i nowszych wersjach:
- Utwórz plik
$(TARGET_DEVICE_DIR)/android_filesystem_config.h. - Dodaj
fs_config_dirslubfs_config_filesdoPRODUCT_PACKAGESw pliku konfiguracji płyty (np.$(TARGET_DEVICE_DIR)/device.mk).
Przykład zastąpienia
Ten przykład pokazuje poprawkę zastępującą demona system/bin/glgps , aby dodać obsługę blokady uśpienia w device/vendor/device katalogu. Pamiętaj o tych kwestiach:
- Każdy wpis struktury to tryb, uid, gid, możliwości i nazwa.
system/core/include/private/android_filesystem_config.hjest uwzględniany automatycznie, aby udostępnić manifest #defines (AID_ROOT,AID_SHELL,CAP_BLOCK_SUSPEND). - Sekcja
android_device_files[]zawiera działanie, które blokuje dostęp dosystem/etc/fs_config_dirsgdy nie jest określony, co stanowi dodatkowe zabezpieczenie DAC w przypadku braku treści do zastąpienia katalogu. Jest to jednak słaba ochrona. Jeśli ktoś ma kontrolę nad/system, zwykle może zrobić wszystko.
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 file system
+** 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)
Migracja systemów plików z wcześniejszych wersji
Podczas migracji systemów plików z Androida 5.x i starszych wersji pamiętaj, że Android 6.x
- usuwa niektóre dołączane pliki, struktury i definicje wbudowane;
- wymaga odwołania do
libcutilszamiast bezpośredniego uruchamiania zsystem/core/include/private/android_filesystem_config.h. Prywatne pliki wykonywalne producenta urządzenia, które zależą odsystem/code/include/private_filesystem_config.hw przypadku struktur plików lub katalogów albo odfs_configmuszą dodaćlibcutilszależności biblioteki. - wymaga prywatnych kopii gałęzi producenta urządzenia
system/core/include/private/android_filesystem_config.hz dodatkową treścią w istniejących celach, aby przenieść je dodevice/vendor/device/android_filesystem_config.h. - zastrzega sobie prawo do stosowania obowiązkowych kontroli dostępu SELinux (MAC) do
plików konfiguracji w systemie docelowym. Implementacje, które obejmują niestandardowe
pliki wykonywalne docelowe używające
fs_config(), muszą zapewnić dostęp.