Объекты файловой системы и службы, добавляемые в сборку, часто требуют отдельных уникальных идентификаторов, известных как идентификаторы Android (AID). В настоящее время многие ресурсы, такие как файлы и службы, без необходимости используют основные (определенные Android) AID; во многих случаях вместо них можно использовать AID OEM (определенные OEM).
Более ранние версии 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 Open Source Project (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Становится:
- Дружественное имя: система
- uid: 1000
- gid: 1000
Чтобы добавить новый AID ядра AOSP, просто добавьте директиву #define в заголовочный файл android_filesystem_config.h . AID генерируется при сборке и становится доступным для интерфейсов, использующих аргументы user и group. Инструментарий проверяет, не находится ли новый AID в диапазонах APP или OEM; он также учитывает изменения в этих диапазонах и должен автоматически перенастраиваться при изменениях или появлении новых зарезервированных OEM диапазонов.
Настройка идентификаторов пользователей
Для включения нового механизма AID установите значение TARGET_FS_CONFIG_GEN в файле BoardConfig.mk . Эта переменная содержит список конфигурационных файлов, что позволяет добавлять файлы по мере необходимости.
По общепринятой практике, файлы конфигурации используют имя config.fs , но на практике можно использовать любое имя. Файлы config.fs имеют формат ini, используемый Python ConfigParser , и включают раздел caps (для настройки возможностей файловой системы) и раздел AIDs (для настройки OEM AID).
Настройте раздел "Заглавные буквы"
Раздел caps позволяет задавать возможности файловой системы для объектов файловой системы в процессе сборки (сама файловая система также должна поддерживать эту функциональность).
Поскольку запуск стабильной службы от имени root в Android приводит к ошибке в наборе тестов совместимости (CTS) , ранее для сохранения прав доступа во время работы процесса или службы требовалось сначала установить права доступа, а затем использовать setuid / setgid для присвоения соответствующего AID. С использованием caps эти требования можно обойти, и ядро сделает это за вас. Когда управление передается функции main() , ваш процесс уже обладает необходимыми правами доступа, поэтому ваша служба может использовать пользователя и группу, не являющиеся root (это предпочтительный способ запуска привилегированных служб).
В разделе Caps Lock используется следующий синтаксис:
| Раздел | Ценить | Определение |
|---|---|---|
[path] | Путь к файловой системе для настройки. Путь, заканчивающийся на /, считается каталогом, в противном случае — файлом. Указание нескольких разделов с одним и тем же [path] в разных файлах является ошибкой. В версиях Python <= 3.2 один и тот же файл может содержать разделы, которые переопределяют предыдущий раздел; в Python 3.2 это устанавливается в строгий режим. | |
mode | Восьмеричный файловый режим | Допустимый восьмеричный формат файла, состоящий как минимум из 3 цифр. Если указано 3, перед ним ставится префикс 0, в противном случае используется формат без изменений. |
user | AID_<user> | Либо define AID на языке C, либо понятное имя (например, допустимы как AID_RADIO , так и radio ). Чтобы определить пользовательский AID, см. раздел «Настройка AID» . |
group | AID_<group> | То же самое, что и у пользователя. |
caps | крышка* | Имя, указанное в файле bionic/libc/kernel/uapi/linux/capability.h без префикса CAP_ . Допускается использование смешанного регистра. Caps также может быть в исходном виде:
|
Пример использования см. в разделе «Использование возможностей файловой системы» .
Настройте раздел AID.
Раздел AID содержит идентификаторы OEM и использует следующий синтаксис:
| Раздел | Ценить | Определение |
|---|---|---|
[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-ID
Чтобы задать 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 добавьте в соответствующий Makefile модуль oemaids_headers и добавьте #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на существующих целевых устройствах требуется наличие копий файла system/core/include/private/android_filesystem_config.h из частной ветки производителя устройства с дополнительным содержимым. - Компания оставляет за собой право применять обязательные средства контроля доступа SELinux (MAC) к конфигурационным файлам в целевой системе; реализации, включающие пользовательские исполняемые файлы целевой системы, использующие
fs_config()должны обеспечивать доступ.