Объектам и службам файловой системы, добавляемым в сборку, часто требуются отдельные уникальные идентификаторы, известные как идентификаторы Android (AID). В настоящее время многие ресурсы, такие как файлы и службы, без необходимости используют базовые (определенные Android) AID; во многих случаях вместо этого можно использовать OEM (определенные OEM) AID.
Более ранние версии Android (Android 7.x и ниже) расширяли механизм AID, используя файл android_filesystem_config.h
для конкретного устройства, чтобы указать возможности файловой системы и/или пользовательские OEM-AID. Однако эта система была неинтуитивной, поскольку она не поддерживала использование красивых имен для OEM-AID, требуя от вас указания необработанных числовых значений для полей пользователя и группы без возможности связать понятное имя с числовым AID.
Более новые версии Android (Android 8.0 и выше) поддерживают новый метод расширения возможностей файловой системы. Этот новый метод поддерживает следующее:
- Несколько исходных расположений для файлов конфигурации (обеспечивает расширяемые конфигурации сборки).
- Проверка работоспособности значений OEM AID во время сборки.
- Создание пользовательского заголовка OEM AID, который при необходимости можно использовать в исходных файлах.
- Ассоциация понятного имени с фактическим значением OEM AID. Поддерживает нечисловые строковые аргументы для пользователя и группы, т. е. «foo» вместо «2901».
Дополнительные улучшения включают удаление массива android_ids[]
из system/core/libcutils/include/private/android_filesystem_config.h
. Этот массив теперь существует в Bionic как полностью частный сгенерированный массив с методами доступа с помощью getpwnam()
и getgrnam()
. (Побочным эффектом этого является создание стабильных двоичных файлов при изменении основных AID.) Инструменты и файл README с более подробной информацией можно найти в build/make/tools/fs_config
.
Добавить идентификаторы Android (AID)
В Android 8.0 массив android_ids[]
удален из проекта Android с открытым исходным кодом (AOSP). Вместо этого все имена, совместимые с AID, генерируются из заголовочного файла system/core/libcutils/include/private/android_filesystem_config.h
при создании массива Bionic android_ids[]
. Любое define
соответствующее AID_*
улавливается инструментом, и * становится именем в нижнем регистре.
Например, в private/android_filesystem_config.h
:
#define AID_SYSTEM 1000
Становится:
- Понятное имя: система
- идентификатор: 1000
- гид: 1000
Чтобы добавить новый основной AID AOSP, просто добавьте #define
в заголовочный файл android_filesystem_config.h
. AID генерируется при сборке и доступен для интерфейсов, использующих аргументы пользователя и группы. Инструменты подтверждают, что новый AID не соответствует диапазонам APP или OEM; он также учитывает изменения в этих диапазонах и должен автоматически перенастраиваться при изменениях или новых диапазонах, зарезервированных OEM.
Настройка идентификаторов AID
Чтобы включить новый механизм AID, установите TARGET_FS_CONFIG_GEN
в файле BoardConfig.mk
. Эта переменная содержит список файлов конфигурации, что позволяет добавлять файлы по мере необходимости.
По соглашению файлы конфигурации используют имя config.fs
, но на практике вы можете использовать любое имя. Файлы config.fs
имеют ini-формат Python ConfigParser и включают раздел caps (для настройки возможностей файловой системы) и раздел AID (для настройки OEM AID).
Настройте раздел заглавных букв
Раздел caps поддерживает настройку возможностей файловой системы для объектов файловой системы в сборке (сама файловая система также должна поддерживать эту функцию).
Поскольку запуск стабильной службы с правами root в Android приводит к сбою пакета тестов совместимости (CTS) , предыдущие требования для сохранения возможности во время запуска процесса или службы включали настройку возможностей, а затем использование setuid
/ setgid
для правильного запуска AID. Используя ограничения, вы можете пропустить эти требования и позволить ядру сделать это за вас. Когда управление передается main()
, ваш процесс уже имеет необходимые ему возможности, поэтому ваша служба может использовать пользователя и группу без полномочий root (это предпочтительный способ запуска привилегированных служб).
В разделе caps используется следующий синтаксис:
Раздел | Ценить | Определение |
---|---|---|
[path] | Путь файловой системы для настройки. Путь, заканчивающийся на /, считается каталогом, в противном случае это файл. Указание нескольких разделов с одним и тем же [path] в разных файлах является ошибкой. В версиях Python <= 3.2 один и тот же файл может содержать разделы, переопределяющие предыдущий раздел; в Python 3.2 установлен строгий режим. | |
mode | Восьмеричный файловый режим | Допустимый восьмеричный формат файла, содержащий не менее 3 цифр. Если указано 3, перед ним ставится префикс 0, в противном случае режим используется как есть. |
user | AID_<пользователь> | Либо C define действительный AID, либо понятное имя (например, приемлемы и AID_RADIO и radio ). Чтобы определить собственный AID, см. раздел «Настройка AID» . |
group | AID_<группа> | То же, что пользователь. |
caps | кепка* | Имя, объявленное в bionic/libc/kernel/uapi/linux/capability.h без начального CAP_ . Допускается смешанный случай. Шапки также могут быть сырыми:
|
Пример использования см. в разделе Использование возможностей файловой системы .
Настройте раздел AID
Раздел AID содержит OEM AID и использует следующий синтаксис:
Раздел | Ценить | Определение |
---|---|---|
[AID_<name>] | <name> может содержать символы в верхнем регистре, цифры и символы подчеркивания. Версия в нижнем регистре используется в качестве понятного имени. Сгенерированный файл заголовка для включения кода использует точный AID_<name> .Указание нескольких разделов с одним и тем же AID_<name> (регистронезависимо с теми же ограничениями, что и [path] ) является ошибкой.<name> должно начинаться с имени раздела, чтобы гарантировать, что оно не конфликтует с разными источниками. | |
value | <номер> | Допустимая числовая строка в стиле C (шестнадцатеричная, восьмеричная, двоичная и десятичная). Указание нескольких разделов с одинаковым значением параметра является ошибкой. Опции значений должны быть указаны в диапазоне, соответствующем разделу, используемому в <name> . Список допустимых разделов и соответствующие им диапазоны определены в system/core/libcutils/include/private/android_filesystem_config.h . Возможные варианты:
|
Примеры использования см. в разделах «Определение имен OEM AID» и «Использование OEM AID» .
Примеры использования
В следующих примерах подробно описано, как определить и использовать OEM AID и как включить возможности файловой системы. Имена OEM AID ( [AID_ name ] ) должны начинаться с имени раздела, например « vendor_ », чтобы гарантировать, что они не конфликтуют с будущими именами AOSP или другими разделами.
Определите имена OEM AID
Чтобы определить OEM AID, создайте файл config.fs
и установите значение AID. Например, в device/x/y/config.fs
установите следующее:
[AID_VENDOR_FOO] value: 2900
После создания файла установите переменную TARGET_FS_CONFIG_GEN
и укажите ее в BoardConfig.mk
. Например, в device/x/y/BoardConfig.mk
установите следующее:
TARGET_FS_CONFIG_GEN += device/x/y/config.fs
Ваш собственный AID теперь может использоваться системой в целом в новой сборке.
Используйте OEM-помощники
Чтобы использовать OEM AID, в коде C включите oemaids_headers
в связанный файл Makefile и добавьте #include "generated_oem_aid.h"
, а затем начните использовать объявленные идентификаторы. Например, в my_file.c
добавьте следующее:
#include "generated_oem_aid.h" … If (ipc->uid == AID_VENDOR_FOO) { // Do something ...
В связанный файл Android.bp
добавьте следующее:
header_libs: ["oemaids_headers"],
Если вы используете файл Android.mk
, добавьте следующее:
LOCAL_HEADER_LIBRARIES := oemaids_headers
Используйте понятные имена
В Android 9 вы можете использовать понятное имя для любого интерфейса, поддерживающего имена AID. Например:
- В команде
chown
вsome/init.rc
:chown vendor_foo /vendor/some/vendor_foo/file
- В
service
some/init.rc
:service vendor_foo /vendor/bin/foo_service user vendor_foo group vendor_foo
Поскольку внутреннее сопоставление понятного имени с uid выполняется с помощью /vendor/etc/passwd
и /vendor/etc/group
, необходимо смонтировать раздел поставщика.
Ассоциированные понятные имена
Android 9 включает поддержку связывания понятного имени с фактическим значением OEM AID. Вы можете использовать нечисловые строковые аргументы для пользователя и группы, то есть « vendor_ foo» вместо «2901».
Преобразование из AID в понятные имена
Для OEM AID Android 8.x требовал использования oem_####
с getpwnam
и подобных функций, а также в местах, которые обрабатывают поиск с помощью getpwnam
(например, сценарии init
). В Android 9 вы можете использовать друзья getpwnam
и getgrnam
в Bionic для преобразования идентификаторов Android (AID) в понятные имена и наоборот.
Используйте возможности файловой системы
Чтобы включить возможности файловой системы, создайте раздел caps в файле config.fs
. Например, в device/x/y/config.fs
добавьте следующий раздел:
[system/bin/foo_service] mode: 0555 user: AID_VENDOR_FOO group: AID_SYSTEM caps: SYS_ADMIN | SYS_NICE
После создания файла установите TARGET_FS_CONFIG_GEN
так, чтобы он указывал на этот файл в BoardConfig.mk
. Например, в device/x/y/BoardConfig.mk
установите следующее:
TARGET_FS_CONFIG_GEN += device/x/y/config.fs
Когда выполняется vendor_ foo
, она начинается с возможностей CAP_SYS_ADMIN
и CAP_SYS_NICE
без вызовов setuid
и setgid
. Кроме того, политика SELinux vendor_ foo
больше не требует возможности setuid
и setgid
и может быть удалена.
Настройка переопределений (Android 6.x-7.x)
В Android 6.0 fs_config
и связанные с ним определения структуры ( system/core/include/private/android_filesystem_config.h
) были перемещены в system/core/libcutils/fs_config.c
где их можно было обновить или переопределить двоичными файлами, установленными в /system/etc/fs_config_dirs
и /system/etc/fs_config_files
. Использование отдельных правил сопоставления и анализа для каталогов и файлов (которые могут использовать дополнительные выражения glob) позволило Android обрабатывать каталоги и файлы в двух разных таблицах. Определения структуры в system/core/libcutils/fs_config.c
не только позволяли читать каталоги и файлы во время выполнения, но хост мог использовать те же файлы во время сборки для создания образов файловой системы как ${OUT}/system/etc/fs_config_dirs
и ${OUT}/system/etc/fs_config_files
.
Хотя метод переопределения расширения файловой системы был заменен модульной системой конфигурации, представленной в Android 8.0, при желании вы все равно можете использовать старый метод. В следующих разделах подробно описано, как создавать и включать файлы переопределения, а также настраивать файловую систему.
Создать файлы переопределения
Вы можете сгенерировать выровненные двоичные файлы /system/etc/fs_config_dirs
и /system/etc/fs_config_files
с помощью инструмента fs_config_generate
в build/tools/fs_config
. Инструмент использует функцию библиотеки libcutils
( fs_config_generate()
) для управления требованиями DAC в буфере и определяет правила для включаемого файла для институционализации правил DAC.
Для использования создайте включаемый файл в файле device/ vendor / device /android_filesystem_config.h
, который будет действовать как переопределение. Файл должен использовать structure fs_path_config
, определенную в system/core/include/private/android_filesystem_config.h
со следующей инициализацией структуры для символов каталога и файла:
- Для каталогов используйте
android _device _dirs[]
. - Для файлов используйте
android _device _files[]
.
Если вы не используете android_device_dirs[]
и android_device_files[]
, вы можете определить NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
и NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES
(см. пример ниже). Вы также можете указать файл переопределения, используя TARGET_ANDROID_FILESYSTEM_CONFIG_H
в конфигурации платы, с обязательным базовым именем android_filesystem_config.h
.
Включить файлы переопределения
Чтобы включить файлы, убедитесь, что PRODUCT_PACKAGES
включает fs_config_dirs
и/или fs_config_files
, чтобы их можно было установить в /system/etc/fs_config_dirs
и /system/etc/fs_config_files
соответственно. Система сборки ищет пользовательский android_filesystem_config.h
в $(TARGET_DEVICE_DIR)
, где существует BoardConfig.mk
. Если этот файл существует где-то еще, установите переменную конфигурации платы TARGET_ANDROID_FILESYSTEM_CONFIG_H
, чтобы она указывала на это место.
Настройте файловую систему
Чтобы настроить файловую систему в Android 6.0 и выше:
- Создайте файл
$(TARGET_DEVICE_DIR)/android_filesystem_config.h
. - Добавьте
fs_config_dirs
и/илиfs_config_files
вPRODUCT_PACKAGES
в файле конфигурации платы (например,$(TARGET_DEVICE_DIR)/device.mk
).
Пример переопределения
В этом примере показан патч для переопределения демона system/bin/glgps
для добавления поддержки блокировки пробуждения в каталоге device/ vendor / device
. Имейте в виду следующее:
- Каждая запись структуры содержит режим, uid, gid, возможности и имя.
system/core/include/private/android_filesystem_config.h
включается автоматически для предоставления #defines манифеста (AID_ROOT
,AID_SHELL
,CAP_BLOCK_SUSPEND
). - Раздел
android_device_files[]
включает действие для подавления доступа кsystem/etc/fs_config_dirs
если оно не указано, что служит дополнительной защитой DAC от отсутствия содержимого для переопределения каталога. Однако это слабая защита; если кто-то контролирует/system
, он обычно может делать все, что захочет.
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)
Миграция файловых систем из более ранних версий
При переносе файловых систем с Android 5.x и более ранних версий имейте в виду, что Android 6.x
- Удаляет некоторые включения, структуры и встроенные определения.
- Требуется ссылка на
libcutils
вместо запуска непосредственно изsystem/core/include/private/android_filesystem_config.h
. Частные исполняемые файлы производителя устройства, которые зависят отsystem/code/include/private_filesystem_config.h
для структур файлов или каталогов илиfs_config
, должны добавлять зависимости библиотекиlibcutils
. - Требуются копии частной ветки производителя устройства
system/core/include/private/android_filesystem_config.h
с дополнительным содержимым на существующих целях для перемещения вdevice/ vendor / device /android_filesystem_config.h
. - Оставляет за собой право применять обязательный контроль доступа (MAC) SELinux к файлам конфигурации в целевой системе; реализации, включающие пользовательские целевые исполняемые файлы с использованием
fs_config()
должны обеспечивать доступ.