Obiekty systemu plików i usługi dodane do kompilacji często wymagają osobnych, 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żna zamiast nich używać identyfikatorów AID producenta OEM.
W wcześniejszych wersjach Androida (Android 7.x i starsze) mechanizm identyfikatorów AID był rozszerzony 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. System ten był jednak nieintuicyjny, ponieważ nie obsługiwał przyjaznych nazw identyfikatorów AID OEM. Wymagało to podania surowych wartości liczbowych w polach użytkownika i grupy bez możliwości powiązania przyjaznej nazwy z liczbowym 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 te opcje:
- wiele źródeł plików konfiguracji (umożliwia rozszerzalne konfiguracje kompilacji);
- Sprawdzanie wartości identyfikatorów AID OEM na etapie kompilacji.
- Generowanie niestandardowego nagłówka OEM AID, którego można używać w plikach źródłowych w razie potrzeby.
- Powiązanie nazwy przyjaznej z rzeczywistą wartością AID OEM. Obsługuje niearytmetyczne argumenty ciągu znaków dotyczące użytkownika i grupy, np. „foo” zamiast „2901”.
Dodatkowe ulepszenia obejmują usunięcie tablicy android_ids[]
z elementu system/core/libcutils/include/private/android_filesystem_config.h
. Ta tablica jest teraz dostępna w Bionic jako całkowicie prywatna generowana tablica z metodami dostępu getpwnam()
i getgrnam()
. (efektem ubocznym jest tworzenie stabilnych plików binarnych, gdy zmieniają się podstawowe identyfikatory AID). Więcej informacji o narzędziach i pliku README znajdziesz w artykule 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 zgodne z AID są zamiast tego generowane z pliku nagłówka system/core/libcutils/include/private/android_filesystem_config.h
podczas generowania tablicy Bionic android_ids[]
. Wszystkie define
pasujące do AID_*
są rozpoznawane przez narzędzia, a * staje się nazwą w małej literze.
Na przykład w private/android_filesystem_config.h
:
#define AID_SYSTEM 1000
Zmiana:
- Przyjazna nazwa: system
- uid: 1000
- gid: 1000
Aby dodać nowy podstawowy identyfikator AOSP, po prostu dodaj plik #define
do pliku nagłówka android_filesystem_config.h
. AID jest generowany podczas kompilacji i staje się dostępny dla interfejsów, które używają argumentów użytkownika i grupy. Narzędzie sprawdza, czy nowy identyfikator AID nie mieści się w zakresie identyfikatorów APP ani OEM. Uwzględnia też zmiany w tych zakresach i powinna automatycznie przekonfigurować się po zmianach lub nowych zakresach zarezerwowanych przez OEM.
Konfigurowanie identyfikatorów AID
Aby włączyć nowy mechanizm identyfikatorów AID, ustaw wartość TARGET_FS_CONFIG_GEN
w pliku BoardConfig.mk
. Ta zmienna przechowuje listę plików konfiguracyjnych, co umożliwia dołączanie plików w razie potrzeby.
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 Pythona i zawierają sekcję caps (do konfigurowania możliwości systemu plików) oraz sekcję AID (do konfigurowania identyfikatorów AID OEM).
Konfigurowanie sekcji z wielkimi literami
Sekcja caps umożliwia konfigurowanie funkcji systemu plików w obiektach systemu plików w ramach kompilacji (system plików musi też obsługiwać tę funkcję).
Uruchomienie stabilnej usługi jako root na Androidzie powoduje niepowodzenie Compatibility Test Suite (CTS), więc poprzednie wymagania dotyczące zachowania możliwości podczas uruchamiania procesu lub usługi obejmowały konfigurowanie możliwości, a następnie używanie setuid
/setgid
do uruchamiania odpowiedniego identyfikatora AID. Dzięki temu możesz pominąć te wymagania i pozwolić jądro na wykonanie tej czynności za Ciebie. Gdy przekazanie kontroli do main()
, proces ma już wymagane możliwości, aby usługa mogła używać użytkownika i grupy niebędącej użytkownikiem root (jest to preferowany sposób uruchamiania usług uprzywilejowanych).
Sekcja z wielkimi literami używa tej składni:
Sekcja | Wartość | Definicja |
---|---|---|
[path] |
Ścieżka do konfigurowania systemu plików. Ścieżka kończąca się na / jest uważana za katalog, w przeciwnym razie jest plikiem.
Podanie w różnych plikach kilku sekcji o tej samej nazwie [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 on ustawiony na tryb ścisły. |
|
mode |
Tryb pliku octal | Prawidłowy octal file mode o długości co najmniej 3 cyfry. Jeśli podano wartość 3, przed nią dodawana jest litera 0, w przeciwnym razie tryb jest używany bez zmian. |
user |
AID_<user> | C define dla prawidłowego identyfikatora AID lub nazwa przyjazna (np. AID_RADIO i radio są akceptowane). Aby zdefiniować niestandardowy identyfikator AID, zapoznaj się z sekcją Konfigurowanie identyfikatora AID. |
group |
AID_<group> | Taki sam jak w przypadku użytkownika. |
caps |
cap* | Nazwa zadeklarowana w bionic/libc/kernel/uapi/linux/capability.h bez CAP_ na początku. Dozwolone są wielkie i małe litery. Znaki wielkie mogą też być:
|
Przykład użycia znajdziesz w artykule Korzystanie z funkcji systemu plików.
Konfigurowanie sekcji AID
Sekcja AID zawiera identyfikatory AID OEM i korzysta z tej składni:
Sekcja | Wartość | Definicja |
---|---|---|
[AID_<name>] |
<name> może zawierać znaki z zadanego zestawu: wielkie litery, cyfry i podkreślenia. Wersja w wersji małej jest używana jako nazwa przyjazna. Wygenerowany plik nagłówka do włączania kodu używa dokładnie tego samego adresu:AID_<name> .
Podawanie wielu sekcji o tej samej nazwie AID_<name> (bez rozróżniania wielkości liter, z tymi samymi ograniczeniami co [path] ) jest błędem. Nazwa <name> musi zaczynać się od nazwy partycji, aby nie powodować konfliktów z innymi źródłami. |
|
value |
<number> | Prawidłowy ciąg znaków liczby w stylu języka C (szeszasta, ósemkowa, binarna i dziesiętna).
Podanie kilku 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 parasmterze <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 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 wchodziły w konflikt z przyszłościowymi nazwami AOSP ani innymi partycjami.
Definiowanie nazw identyfikatorów AID OEM
Aby zdefiniować identyfikator AID OEM, utwórz plik config.fs
i ustaw wartość AID. Na przykład w elemencie device/x/y/config.fs
ustaw:
[AID_VENDOR_FOO] value: 2900
Po utworzeniu pliku ustaw zmienną TARGET_FS_CONFIG_GEN
i od niej odwołuj się w sekcji BoardConfig.mk
. Na przykład w sekcji 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 teraz być używany przez system w ramach nowej wersji.
Korzystanie z identyfikatorów AID OEM
Aby używać identyfikatora AID OEM, w kodzie C uwzględnij w powiązanym pliku Makefile zmienną oemaids_headers
i dodaj #include "generated_oem_aid.h"
, a następnie zacznij używać zadeklarowanych identyfikatorów. Na przykład w elemencie my_file.c
dodaj te informacje:
#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 dowolnym interfejsie, który obsługuje nazwy AID. Przykład:
- W komendach
chown
w sekcjisome/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 unikatowy jest wykonywane przez /vendor/etc/passwd
i /vendor/etc/group
, partycja dostawcy musi być zamontowana.
Powiązywanie przyjaznych nazw
Android 9 obsługuje łączenie nazwy przyjaznej z rzeczywistą wartością AID OEM. W przypadku użytkownika i grupy możesz używać niearytmetycznych ciągów znaków, np. „vendor_foo” zamiast „2901”.
Konwertowanie identyfikatorów AID na nazwy przyjazne
W Androidzie 8.x w przypadku identyfikatorów OEM wymagane było używanie funkcji oem_####
z funkcją getpwnam
i podobnymi, a także w miejscach, które obsługują wyszukiwanie za pomocą funkcji getpwnam
(np. skrypty 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 możliwości 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 parametr TARGET_FS_CONFIG_GEN
tak, aby wskazywał ten plik w pliku BoardConfig.mk
. Na przykład w sekcji 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, uruchamia się z możliwościami CAP_SYS_ADMIN
i CAP_SYS_NICE
bez wywołań setuid
i setgid
. Ponadto zasady SELinux usługi vendor_foo
nie wymagają już uprawnień setuid
i setgid
, więc można je usunąć.
Konfigurowanie zastąpień (Android 6.x–7.x)
W Androidzie 6.0 funkcja fs_config
i powiązane z nią definicje struktury (system/core/include/private/android_filesystem_config.h
) zostały przeniesione do pliku system/core/libcutils/fs_config.c
, gdzie można je aktualizować lub zastępować za pomocą plików binarnych zainstalowanych w folderach /system/etc/fs_config_dirs
i /system/etc/fs_config_files
. Korzystanie z osobnych reguł dopasowywania i analizowania katalogów i plików (które mogą używać dodatkowych wyrażeń ogólnych) 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 odczyt katalogów i plików w czasie wykonywania, ale także używanie tych samych plików podczas kompilacji do tworzenia obrazów systemu plików, tak jak w ${OUT}/system/etc/fs_config_dirs
i ${OUT}/system/etc/fs_config_files
.
Chociaż metoda zastępowania służąca do rozszerzania systemu plików została zastąpiona przez modułowy system konfiguracji wprowadzony w Androidzie 8.0, w razie potrzeby nadal możesz używać starszej metody. W następnych sekcjach znajdziesz szczegółowe informacje o generowaniu i dołączaniu plików, zastępowaniu plików i konfigurowaniu systemu plików.
Generowanie plików zastąpienia
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 DAC w buforze, oraz definiuje reguły dla pliku include, aby ustanowić reguły DAC.
Aby użyć tej funkcji, utwórz plik include w folderze device/vendor/device/android_filesystem_config.h
, który będzie działać jako zastąpienie. Plik musi być w formacie structure fs_path_config
zdefiniowanym w pliku system/core/include/private/android_filesystem_config.h
z tymi wstępnymi wartościami struktury dla symboli katalogu i pliku:
- W przypadku katalogów użyj elementu
android_device_dirs[]
. - W przypadku plików użyj
android_device_files[]
.
Jeśli nie używasz właściwości android_device_dirs[]
i android_device_files[]
, możesz zdefiniować właściwości 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ąpienia za pomocą parametru TARGET_ANDROID_FILESYSTEM_CONFIG_H
w konfiguracji karty, z wymuszonym nazwiskiem android_filesystem_config.h
.
Uwzględnij pliki zastępcze
Aby uwzględnić pliki, sprawdź, czy PRODUCT_PACKAGES
zawiera fs_config_dirs
lub fs_config_files
, aby można było zainstalować je odpowiednio w /system/etc/fs_config_dirs
i /system/etc/fs_config_files
. System kompilacji
wyszukuje niestandardowe android_filesystem_config.h
w
$(TARGET_DEVICE_DIR)
, gdzie istnieje BoardConfig.mk
.
Jeśli ten plik istnieje gdzie indziej, 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 lub nowszym:
- Utwórz plik
$(TARGET_DEVICE_DIR)/android_filesystem_config.h
. - Dodaj
fs_config_dirs
lubfs_config_files
doPRODUCT_PACKAGES
w pliku konfiguracji planszy (np.$(TARGET_DEVICE_DIR)/device.mk
).
Przykład zastąpienia
Ten przykład pokazuje poprawkę do zastąpienia demona system/bin/glgps
, aby dodać obsługę blokady aktywacji w katalogu device/vendor/device
. Pamiętaj o tych kwestiach:
- Każdy wpis struktury to tryb, identyfikator użytkownika, identyfikator grupy, możliwości i nazwa.
system/core/include/private/android_filesystem_config.h
jest dołączany automatycznie, aby zapewnić definicje w pliku manifestu (#defines) (AID_ROOT
,AID_SHELL
,CAP_BLOCK_SUSPEND
). - Sekcja
android_device_files[]
zawiera działanie polegające na blokowaniu dostępu dosystem/etc/fs_config_dirs
, gdy nie jest on określony, co stanowi dodatkową ochronę DAC w przypadku braku treści w pliku zastąpień katalogu. Jest to jednak słaba ochrona. Jeśli ktoś ma kontrolę nad/system
, 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 migracji systemów plików z Androida 5.x i starszych pamiętaj, że: Android 6.x
- Usunięcie niektórych include, struktur i definicji w ciele.
- Wymaga odwołania do
libcutils
zamiast uruchamiania bezpośrednio 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 strukturze plików lub katalogów, lubfs_config
, muszą dodaćlibcutils
zależności biblioteki. - Wymaga kopii
system/core/include/private/android_filesystem_config.h
z dodatkowymi treściami dla istniejących celów, które należy przenieść dodevice/vendor/device/android_filesystem_config.h
. - Zastrzega prawo do stosowania mechanizmów kontroli dostępu SELinux (MAC) do plików konfiguracyjnych w systemie docelowym. Wdrożenia, które obejmują niestandardowe pliki wykonywalne docelowe korzystające z
fs_config()
, muszą zapewnić dostęp.