Obiekty i usługi systemu plików dodane do kompilacji często wymagają oddzielnych, unikalnych identyfikatorów, zwanych identyfikatorami Androida (AID). Obecnie wiele zasobów, takich jak pliki i usługi, niepotrzebnie korzysta z identyfikatorów AID zdefiniowanych przez Androida. W wielu przypadkach można zamiast nich używać identyfikatorów AID zdefiniowanych przez producenta OEM.
Starsze wersje Androida (7.x i starsze) rozszerzały mechanizm identyfikatorów AID za pomocą pliku android_filesystem_config.h
specyficznego dla urządzenia, aby określać możliwości systemu plików lub niestandardowe identyfikatory AID OEM. Ten system był jednak nieintuicyjny, ponieważ nie obsługiwał używania przyjaznych nazw w przypadku identyfikatorów AID OEM, co wymagało podawania surowych wartości liczbowych w polach użytkownika i grupy bez możliwości powiązania przyjaznej nazwy z identyfikatorem AID.
Nowsze wersje Androida (8.0 i nowsze) obsługują nową metodę rozszerzania możliwości systemu plików. Ta nowa metoda obsługuje:
- Wiele lokalizacji źródłowych plików konfiguracji (umożliwia rozszerzalne konfiguracje kompilacji).
- Sprawdzanie poprawności wartości OEM AID w czasie kompilacji.
- Generowanie niestandardowego nagłówka OEM AID, którego można w razie potrzeby używać w plikach źródłowych.
- Powiązanie nazwy przyjaznej z rzeczywistą wartością AID OEM. Obsługuje argumenty w postaci ciągów znaków nienumerycznych dla użytkowników i grup, np. „foo” zamiast „2901”.
Dodatkowe ulepszenia obejmują usunięcie tablicy android_ids[]
z
system/core/libcutils/include/private/android_filesystem_config.h
. Ta tablica jest teraz w Bionic w pełni prywatną tablicą wygenerowaną z akcesorami z getpwnam()
i getgrnam()
. (Skutkiem ubocznym jest tworzenie stabilnych plików binarnych, ponieważ modyfikowane są podstawowe identyfikatory AID). Narzędzia i plik README z dodatkowymi informacjami 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 (AOSP). Wszystkie nazwy przyjazne dla AID są generowane z pliku nagłówkowego system/core/libcutils/include/private/android_filesystem_config.h
podczas generowania tablicy Bionic android_ids[]
. Każde define
dopasowanieAID_*
jest wykrywane przez narzędzie, a * staje się nazwą zapisaną małymi literami.
Na przykład w przypadku private/android_filesystem_config.h
:
#define AID_SYSTEM 1000
Zmienia się w:
- Przyjazna nazwa: system
- uid: 1000
- gid: 1000
Aby dodać nowy podstawowy identyfikator AID AOSP, po prostu dodaj #define
do pliku nagłówkowego android_filesystem_config.h
. 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 mieści się w zakresach APP ani OEM. Uwzględnia też zmiany w tych zakresach i powinno automatycznie zmieniać konfigurację w przypadku zmian lub nowych zakresów zarezerwowanych przez producenta OEM.
Konfigurowanie identyfikatorów aplikacji
Aby włączyć nowy mechanizm identyfikatorów reklamowych, w pliku BoardConfig.mk
ustaw wartość TARGET_FS_CONFIG_GEN
. Ta zmienna zawiera listę plików konfiguracyjnych, dzięki czemu możesz w razie potrzeby dołączać pliki.
Zgodnie z konwencją pliki konfiguracji mają nazwę config.fs
, ale w praktyce możesz użyć dowolnej nazwy. Pliki config.fs
są w formacie ini ConfigParser języka Python i zawierają sekcję caps (do konfigurowania możliwości systemu plików) oraz sekcję AIDs (do konfigurowania identyfikatorów AID OEM).
Konfigurowanie sekcji limitów
Sekcja caps umożliwia ustawianie uprawnień systemu plików dla obiektów systemu plików w kompilacji (sam system plików musi też obsługiwać tę funkcję).
Uruchamianie stabilnej usługi jako użytkownik root w Androidzie powoduje błąd Compatibility Test Suite (CTS), dlatego 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 uruchomienia odpowiedniego identyfikatora AID. Dzięki limitom możesz pominąć te wymagania i zlecić to jądru. Gdy kontrola zostanie przekazana do main()
, Twój proces będzie już miał potrzebne uprawnienia, dzięki czemu usługa będzie mogła korzystać z użytkownika i grupy bez uprawnień roota (jest to preferowany sposób uruchamiania usług z uprawnieniami).
Sekcja limitów wykorzystuje tę 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 traktowana jako plik.
Określenie w różnych plikach wielu sekcji o tej samej wartości [path] jest błędem. W wersjach Pythona <= 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 tryb pliku w systemie ósemkowym składający się z co najmniej 3 cyfr. Jeśli podano wartość 3, jest ona poprzedzona zerem. W przeciwnym razie tryb jest używany w niezmienionej postaci. |
user |
AID_<user> | C define w przypadku prawidłowego identyfikatora AID lub nazwa przyjazna (np. akceptowane są zarówno AID_RADIO , jak i radio ). Aby zdefiniować niestandardowy identyfikator aplikacji, zapoznaj się z sekcją Konfigurowanie identyfikatora aplikacji. |
group |
AID_<group> | Taki sam jak użytkownik. |
caps |
cap* | Nazwa zadeklarowana w bionic/libc/kernel/uapi/linux/capability.h bez początkowego znaku CAP_ . Dozwolone są wielkie i małe litery. Limity mogą też być
wartościami:
|
Przykład użycia znajdziesz w sekcji Korzystanie z funkcji systemu plików.
Konfigurowanie sekcji AID
Sekcja AID zawiera identyfikatory AID OEM i ma taką składnię:
Sekcja | Wartość | Definicja |
---|---|---|
[AID_<name>] |
<name> może zawierać znaki z tego zbioru: wielkie litery, cyfry i podkreślenia. Wersja pisana małymi literami jest używana jako nazwa przyjazna. Wygenerowany plik nagłówkowy do włączenia kodu używa dokładnego AID_<name> .
Błędem jest określenie wielu sekcji o tej samej wartości atrybutu AID_<name> (bez rozróżniania wielkości liter, z tymi samymi ograniczeniami co [path] ).<name> musi zaczynać się od nazwy partycji, aby nie powodować konfliktu z różnymi źródłami. |
|
value |
<numer> | Prawidłowy ciąg znaków liczbowych w stylu C (szesnastkowy, ósemkowy, binarny i dziesiętny).
Określenie wielu sekcji z tą samą opcją wartości jest błędem. Opcje wartości muszą być określone w zakresie odpowiadającym partycji użytej 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 sekcjach Definiowanie nazw identyfikatorów AID OEM i Używanie 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ć funkcje systemu plików. Nazwy identyfikatorów AID OEM ([AID_name]) muszą zaczynać się od nazwy partycji, np. „vendor_”, aby nie powodować konfliktów z przyszłymi nazwami AOSP ani innymi partycjami.
Określanie 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 przypadku
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 urządzeń AID OEM
Aby użyć interfejsu AID OEM, w kodzie C umieść oemaids_headers
w powiązanym pliku Makefile i dodaj #include "generated_oem_aid.h"
, a potem zacznij używać zadeklarowanych identyfikatorów. Na przykład w my_file.c
dodaj ten kod:
#include "generated_oem_aid.h" … If (ipc->uid == AID_VENDOR_FOO) { // Do something ...
W powiązanym pliku Android.bp
dodaj te informacje:
header_libs: ["oemaids_headers"],
Jeśli używasz pliku Android.mk
, dodaj te informacje:
LOCAL_HEADER_LIBRARIES := oemaids_headers
Używanie przyjaznych nazw
W Androidzie 9 możesz używać przyjaznej nazwy w przypadku każdego interfejsu, który obsługuje nazwy AID. Na przykład:
- W poleceniu
chown
wsome/init.rc
:chown vendor_foo /vendor/some/vendor_foo/file
- W
service
wsome/init.rc
:service vendor_foo /vendor/bin/foo_service user vendor_foo group vendor_foo
Ponieważ wewnętrzne mapowanie nazwy przyjaznej na identyfikator UID jest wykonywane przez /vendor/etc/passwd
i /vendor/etc/group
, partycja dostawcy musi być zamontowana.
Powiązywanie przyjaznych nazw
Android 9 obsługuje przypisywanie przyjaznej nazwy do rzeczywistej wartości AID OEM. W przypadku argumentów user i group możesz używać ciągów znaków nienumerycznych, czyli np. „vendor_foo” zamiast „2901”.
Konwertowanie identyfikatorów AID na przyjazne nazwy
W przypadku identyfikatorów AID OEM Android 8.x wymagał użycia oem_####
z getpwnam
i podobnymi funkcjami, a także w miejscach, w których wyszukiwania są obsługiwane za pomocą getpwnam
(np. w skryptach init
). 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 funkcji systemu plików
Aby włączyć funkcje 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 zmienną TARGET_FS_CONFIG_GEN
tak, aby wskazywała ten plik w BoardConfig.mk
. Na przykład w przypadku
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 funkcji CAP_SYS_ADMIN
i CAP_SYS_NICE
bez wywołań setuid
i setgid
. Dodatkowo usługa vendor_foo
nie potrzebuje już uprawnień setuid
i setgid
w zasadach SELinux i można je usunąć.
Konfigurowanie zastąpień (Android 6.x–7.x)
Android 6.0 przeniósł 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 było aktualizować lub
zastępować plikami binarnymi zainstalowanymi w /system/etc/fs_config_dirs
i /system/etc/fs_config_files
. Używanie osobnych reguł dopasowywania i parsowania
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 w czasie 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 modułowym systemem konfiguracji wprowadzonym w Androidzie 8.0, ale w razie potrzeby możesz nadal używać starej metody. W kolejnych sekcjach znajdziesz szczegółowe informacje o tym, jak generować i dołączać pliki zastępujące oraz konfigurować system plików.
Generowanie plików zastępujących
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 korzysta z funkcji biblioteki libcutils
(fs_config_generate()
), aby zarządzać wymaganiami dotyczącymi DAC w buforze, i określa reguły dla pliku dołączanego, aby ujednolicić reguły DAC.
Aby go 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 mieć format structure fs_path_config
zdefiniowany w system/core/include/private/android_filesystem_config.h
z następującymi inicjalizacjami struktury dla symboli katalogów i plików:
- W przypadku katalogów użyj elementu
android_device_dirs[]
. - W przypadku plików użyj
android_device_files[]
.
Jeśli nie używasz elementów android_device_dirs[]
i android_device_files[]
, możesz zdefiniować elementy NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
i NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES
(patrz przykład poniżej). Możesz też określić plik zastępujący, używając TARGET_ANDROID_FILESYSTEM_CONFIG_H
w konfiguracji płyty z wymuszonym basename android_filesystem_config.h
.
Uwzględnij pliki zastępujące
Aby uwzględnić pliki, upewnij się, że PRODUCT_PACKAGES
zawiera fs_config_dirs
lub fs_config_files
, aby można było zainstalować je odpowiednio w lokalizacjach /system/etc/fs_config_dirs
i /system/etc/fs_config_files
. System kompilacji wyszukuje niestandardowe 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
, aby wskazywała tę lokalizację.
Konfigurowanie systemu plików
Aby skonfigurować system plików na urządzeniu z Androidem 6.0 lub nowszym:
- Utwórz plik
$(TARGET_DEVICE_DIR)/android_filesystem_config.h
. - Dodaj
fs_config_dirs
lubfs_config_files
doPRODUCT_PACKAGES
w pliku konfiguracji tablicy (np.$(TARGET_DEVICE_DIR)/device.mk
).
Przykład zastąpienia
Ten przykład pokazuje poprawkę zastępującą demona system/bin/glgps
w celu dodania obsługi blokady wybudzania w katalogu device/vendor/device
. 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.h
jest automatycznie uwzględniany, aby udostępniać definicje #define w pliku manifestu (AID_ROOT
,AID_SHELL
,CAP_BLOCK_SUSPEND
). - Sekcja
android_device_files[]
zawiera działanie, które w przypadku braku określenia powoduje zablokowanie dostępu dosystem/etc/fs_config_dirs
. Stanowi to dodatkową ochronę DAC w przypadku braku treści dla zastąpień katalogu. Jest to jednak słaba ochrona. Jeśli ktoś ma kontrolę nad/system
, zwykle może zrobić wszystko, co zechce.
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 przenoszenia systemów plików z Androida 5.x i starszych wersji pamiętaj, że Android 6.x
- Usuwa niektóre instrukcje include, struktury i definicje wbudowane.
- Wymaga odwołania do
libcutils
zamiast 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.h
w przypadku struktur plików lub katalogów albofs_config
, muszą dodać zależności bibliotekilibcutils
. - Wymaga kopii prywatnych gałęzi producenta urządzenia
system/core/include/private/android_filesystem_config.h
z dodatkową zawartością w przypadku istniejących miejsc docelowych, aby przejść nadevice/vendor/device/android_filesystem_config.h
. - Zastrzega sobie prawo do stosowania obowiązkowych kontroli dostępu (MAC) SELinux do plików konfiguracyjnych w systemie docelowym. Implementacje, które zawierają niestandardowe pliki wykonywalne w systemie docelowym, korzystające z funkcji
fs_config()
, muszą zapewniać dostęp.