Los objetos y servicios del sistema de archivos que se agregan a la compilación suelen necesitar IDs únicos y separados, conocidos como IDs de Android (AIDs). Actualmente, muchos recursos, como archivos y servicios, usan AIDs centrales (definidos por Android) de forma innecesaria. En muchos casos, puedes usar AIDs de OEM (definidos por el OEM) en su lugar.
Las versiones anteriores de Android (Android 7.x y versiones anteriores) extendían el mecanismo de AID con un archivo android_filesystem_config.h
específico del dispositivo para especificar las capacidades del sistema de archivos o los AID personalizados del OEM. Sin embargo, este sistema no era intuitivo, ya que no admitía el uso de nombres descriptivos para los AID del OEM, lo que requería que especificaras el valor numérico sin procesar para los campos de usuario y grupo sin una forma de asociar un nombre descriptivo con el AID numérico.
Las versiones más recientes de Android (Android 8.0 y versiones posteriores) admiten un nuevo método para extender las capacidades del sistema de archivos. Este nuevo método admite lo siguiente:
- Múltiples ubicaciones de origen para los archivos de configuración (permite configuraciones de compilación extensibles).
- Se realiza una verificación de integridad en tiempo de compilación de los valores de AID del OEM.
- Generación de un encabezado AID de OEM personalizado que se puede usar en los archivos fuente según sea necesario.
- Asociación de un nombre descriptivo con el valor de AID del OEM real. Admite argumentos de cadenas no numéricas para el usuario y el grupo, es decir, "foo" en lugar de "2901".
Entre las mejoras adicionales, se incluye la eliminación del array android_ids[]
de system/core/libcutils/include/private/android_filesystem_config.h
. Este array ahora existe en Bionic como un array generado completamente privado, con descriptores de acceso con getpwnam()
y getgrnam()
. (Esto tiene el efecto secundario de producir archivos binarios estables a medida que se modifican los AID principales). Para obtener herramientas y un archivo README con más detalles, consulta build/make/tools/fs_config
.
Cómo agregar IDs de Android (AID)
Android 8.0 quitó el array android_ids[]
del Proyecto de código abierto de Android (AOSP). En cambio, todos los nombres compatibles con AID se generan a partir del archivo de encabezado system/core/libcutils/include/private/android_filesystem_config.h
cuando se genera el array android_ids[]
de Bionic. La herramienta selecciona cualquier define
que coincida con AID_*
, y * se convierte en el nombre en minúsculas.
Por ejemplo, en private/android_filesystem_config.h
:
#define AID_SYSTEM 1000
Se convierte en lo siguiente:
- Nombre descriptivo: sistema
- uid: 1000
- gid: 1000
Para agregar un nuevo AID principal del AOSP, simplemente agrega #define
al archivo de encabezado android_filesystem_config.h
. El AID se genera durante la compilación y está disponible para las interfaces que usan argumentos de usuario y grupo. La herramienta valida que el nuevo AID no se encuentre dentro de los rangos de APP o OEM. También respeta los cambios en esos rangos y debería reconfigurarse automáticamente en caso de cambios o nuevos rangos reservados para OEM.
Configura los AIDs
Para habilitar el nuevo mecanismo de AID, configura TARGET_FS_CONFIG_GEN
en el archivo BoardConfig.mk
. Esta variable contiene una lista de archivos de configuración, lo que te permite agregar archivos según sea necesario.
Por convención, los archivos de configuración usan el nombre config.fs
, pero, en la práctica, puedes usar cualquier nombre. Los archivos config.fs
están en el formato ini de ConfigParser de Python y contienen una sección de capacidades (para configurar las capacidades del sistema de archivos) y una sección de AIDs (para configurar los AIDs del OEM).
Cómo configurar la sección de topes
La sección de capacidades admite la configuración de capacidades del sistema de archivos en objetos del sistema de archivos dentro de la compilación (el sistema de archivos en sí también debe admitir esta funcionalidad).
Dado que ejecutar un servicio estable como administrador en Android provoca una falla en el conjunto de pruebas de compatibilidad (CTS), los requisitos anteriores para conservar una capacidad mientras se ejecuta un proceso o servicio implicaban configurar capacidades y, luego, usar setuid
/setgid
para un AID adecuado para ejecutar. Con los límites, puedes omitir estos requisitos y dejar que el kernel lo haga por ti. Cuando el control se entrega a main()
, tu proceso ya tiene las capacidades que necesita para que tu servicio pueda usar un usuario y un grupo no raíz (esta es la forma preferida de iniciar servicios con privilegios).
La sección de límites usa la siguiente sintaxis:
Sección | Valor | Definición |
---|---|---|
[path] |
Es la ruta de acceso del sistema de archivos que se configurará. Una ruta que termina en / se considera un directorio; de lo contrario, se considera un archivo.
Es un error especificar varias secciones con el mismo [path] en diferentes archivos. En las versiones de Python <= 3.2, el mismo archivo puede contener secciones que anulan la sección anterior. En Python 3.2, se establece en modo estricto. |
|
mode |
Modo de archivo octal | Modo de archivo octal válido de al menos 3 dígitos. Si se especifica 3, se le agrega un 0 como prefijo; de lo contrario, el modo se usa tal como está. |
user |
AID_<user> | Puede ser la C define para un AID válido o el nombre descriptivo
(p.ej., tanto AID_RADIO como radio son aceptables). Para definir un AID personalizado, consulta la sección sobre cómo configurar el AID. |
group |
AID_<group> | Es igual al usuario. |
caps |
cap* | El nombre tal como se declaró en bionic/libc/kernel/uapi/linux/capability.h , sin el CAP_ inicial. Se permite el uso de mayúsculas y minúsculas combinadas. Las tapas también pueden ser sin procesar:
|
Para ver un ejemplo de uso, consulta Cómo usar las capacidades del sistema de archivos.
Configura la sección de AID
La sección AID contiene los AID del OEM y usa la siguiente sintaxis:
Sección | Valor | Definición |
---|---|---|
[AID_<name>] |
El <name> puede contener caracteres en mayúscula, números y guiones bajos. La versión en minúsculas se usa como el nombre descriptivo. El archivo de encabezado generado para la inclusión de código usa el AID_<name> exacto.
Es un error especificar varias secciones con el mismo AID_<name> (no distingue mayúsculas de minúsculas y tiene las mismas restricciones que [path] ).
<name> debe comenzar con un nombre de partición para garantizar que no entre en conflicto con diferentes fuentes. |
|
value |
<número> | Es una cadena de números válida de estilo C (hexadecimal, octal, binaria y decimal).
Es un error especificar varias secciones con la misma opción de valor. Las opciones de valor deben especificarse en el rango correspondiente a la partición utilizada en <name> . La lista de particiones válidas y sus rangos correspondientes se define en system/core/libcutils/include/private/android_filesystem_config.h .
Las opciones son las siguientes:
|
Para ver ejemplos de uso, consulta Cómo definir nombres de AID de OEM y Cómo usar AID de OEM.
Ejemplos de uso
En los siguientes ejemplos, se detalla cómo definir y usar un AID del OEM, y cómo habilitar las capacidades del sistema de archivos. Los nombres de AID del OEM ([AID_nombre]) deben comenzar con un nombre de partición, como "vendor_", para garantizar que no entren en conflicto con futuros nombres de AOSP o con otras particiones.
Cómo definir nombres de AID de OEM
Para definir un AID del OEM, crea un archivo config.fs
y establece el valor del AID. Por ejemplo, en device/x/y/config.fs
, configura lo siguiente:
[AID_VENDOR_FOO] value: 2900
Después de crear el archivo, establece la variable TARGET_FS_CONFIG_GEN
y apunta a ella en BoardConfig.mk
. Por ejemplo, en device/x/y/BoardConfig.mk
, configura lo siguiente:
TARGET_FS_CONFIG_GEN += device/x/y/config.fs
Ahora, el sistema en general puede consumir tu AID personalizado en una nueva compilación.
Usa AID de OEM
Para usar un AID del OEM, en tu código C, incluye oemaids_headers
en tu Makefile asociado y agrega #include "generated_oem_aid.h"
. Luego, comienza a usar los identificadores declarados. Por ejemplo, en my_file.c
, agrega lo siguiente:
#include "generated_oem_aid.h" … If (ipc->uid == AID_VENDOR_FOO) { // Do something ...
En el archivo Android.bp
asociado, agrega lo siguiente:
header_libs: ["oemaids_headers"],
Si usas un archivo Android.mk
, agrega lo siguiente:
LOCAL_HEADER_LIBRARIES := oemaids_headers
Usa nombres fáciles de usar
En Android 9, puedes usar el nombre descriptivo para cualquier interfaz que admita nombres de AID. Por ejemplo:
- En un comando
chown
ensome/init.rc
, haz lo siguiente:chown vendor_foo /vendor/some/vendor_foo/file
- En un
service
ensome/init.rc
, haz lo siguiente:service vendor_foo /vendor/bin/foo_service user vendor_foo group vendor_foo
Dado que la asignación interna del nombre descriptivo al UID se realiza mediante /vendor/etc/passwd
y /vendor/etc/group
, se debe activar la partición del proveedor.
Asocia nombres descriptivos
Android 9 incluye compatibilidad para asociar un nombre descriptivo con el valor real del AID del OEM. Puedes usar argumentos de cadena no numéricos para el usuario y el grupo, es decir, "vendor_foo" en lugar de "2901".
Cómo convertir de AID a nombres fáciles de usar
En el caso de los AID del OEM, Android 8.x requería el uso de oem_####
con getpwnam
y funciones similares, así como en lugares que controlan las búsquedas con getpwnam
(como las secuencias de comandos de init
). En Android 9, puedes usar los amigos getpwnam
y getgrnam
en Bionic para convertir IDs de Android (AIDs) en nombres descriptivos y viceversa.
Usa las funciones del sistema de archivos
Para habilitar las funciones del sistema de archivos, crea una sección de capacidades en el archivo config.fs
. Por ejemplo, en device/x/y/config.fs
, agrega la siguiente sección:
[system/bin/foo_service] mode: 0555 user: AID_VENDOR_FOO group: AID_SYSTEM caps: SYS_ADMIN | SYS_NICE
Después de crear el archivo, configura TARGET_FS_CONFIG_GEN
para que apunte a ese archivo en BoardConfig.mk
. Por ejemplo, en device/x/y/BoardConfig.mk
, configura lo siguiente:
TARGET_FS_CONFIG_GEN += device/x/y/config.fs
Cuando se ejecuta el servicio vendor_foo
, comienza con las capacidades CAP_SYS_ADMIN
y CAP_SYS_NICE
sin llamadas a setuid
ni setgid
. Además, la política de SELinux del servicio vendor_foo
ya no necesita las capacidades setuid
y setgid
, y se puede borrar.
Cómo configurar anulaciones (Android 6.x a 7.x)
Android 6.0 reubicó fs_config
y las definiciones de estructura asociadas (system/core/include/private/android_filesystem_config.h
) en system/core/libcutils/fs_config.c
, donde los archivos binarios instalados en /system/etc/fs_config_dirs
y /system/etc/fs_config_files
podían actualizarlos o anularlos. El uso de reglas independientes de coincidencia y análisis para directorios y archivos (que podrían usar expresiones glob adicionales) permitió que Android controlara directorios y archivos en dos tablas diferentes.
Las definiciones de estructura en system/core/libcutils/fs_config.c
no solo permitían la lectura en tiempo de ejecución de directorios y archivos, sino que el host podía usar los mismos archivos durante el tiempo de compilación para construir imágenes del sistema de archivos como ${OUT}/system/etc/fs_config_dirs
y ${OUT}/system/etc/fs_config_files
.
Si bien el método de anulación para extender el sistema de archivos se reemplazó por el sistema de configuración modular que se introdujo en Android 8.0, aún puedes usar el método anterior si lo deseas. En las siguientes secciones, se detalla cómo generar e incluir archivos de anulación, y cómo configurar el sistema de archivos.
Cómo generar archivos de anulación
Puedes generar los archivos binarios alineados /system/etc/fs_config_dirs
y /system/etc/fs_config_files
con la herramienta fs_config_generate
en build/tools/fs_config
. La herramienta usa una función de biblioteca libcutils
(fs_config_generate()
) para administrar los requisitos de la DAC en un búfer y define reglas para un archivo de inclusión para institucionalizar las reglas de la DAC.
Para usarlo, crea un archivo de inclusión en device/vendor/device/android_filesystem_config.h
que actúe como anulación. El archivo debe usar el formato structure fs_path_config
definido en system/core/include/private/android_filesystem_config.h
con las siguientes inicializaciones de estructura para los símbolos de directorio y archivo:
- Para los directorios, usa
android_device_dirs[]
. - Para los archivos, usa
android_device_files[]
.
Cuando no se usan android_device_dirs[]
y android_device_files[]
, puedes definir NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
y NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES
(consulta el ejemplo a continuación). También puedes especificar el archivo de anulación con TARGET_ANDROID_FILESYSTEM_CONFIG_H
en la configuración de la placa, con un nombre base obligatorio de android_filesystem_config.h
.
Cómo incluir archivos de anulación
Para incluir archivos, asegúrate de que PRODUCT_PACKAGES
incluya fs_config_dirs
o fs_config_files
para que pueda instalarlos en /system/etc/fs_config_dirs
y /system/etc/fs_config_files
, respectivamente. El sistema de compilación busca android_filesystem_config.h
personalizado en $(TARGET_DEVICE_DIR)
, donde existe BoardConfig.mk
.
Si este archivo existe en otro lugar, configura la variable de configuración de la placa TARGET_ANDROID_FILESYSTEM_CONFIG_H
para que apunte a esa ubicación.
Configura el sistema de archivos
Para configurar el sistema de archivos en Android 6.0 y versiones posteriores, haz lo siguiente:
- Crea el archivo
$(TARGET_DEVICE_DIR)/android_filesystem_config.h
. - Agrega
fs_config_dirs
ofs_config_files
aPRODUCT_PACKAGES
en el archivo de configuración de la placa (p.ej.,$(TARGET_DEVICE_DIR)/device.mk
).
Ejemplo de anulación
En este ejemplo, se muestra un parche para anular el daemon system/bin/glgps
y agregar compatibilidad con el bloqueo de activación en el directorio device/vendor/device
. Ten en cuenta lo siguiente:
- Cada entrada de estructura es el modo, el UID, el GID, las capacidades y el nombre.
system/core/include/private/android_filesystem_config.h
se incluye automáticamente para proporcionar las definiciones de preprocesador del manifiesto (AID_ROOT
,AID_SHELL
,CAP_BLOCK_SUSPEND
). - La sección
android_device_files[]
incluye una acción para suprimir el acceso asystem/etc/fs_config_dirs
cuando no se especifica, lo que sirve como protección adicional de DAC por falta de contenido para las anulaciones de directorios. Sin embargo, esta es una protección débil. Si alguien tiene control sobre/system
, por lo general, puede hacer lo que quiera.
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)
Migra sistemas de archivos desde versiones anteriores
Cuando migres sistemas de archivos desde Android 5.x y versiones anteriores, ten en cuenta que Android 6.x
- Se quitan algunas inclusiones, estructuras y definiciones intercaladas.
- Requiere una referencia a
libcutils
en lugar de ejecutarse directamente desdesystem/core/include/private/android_filesystem_config.h
. Los ejecutables privados del fabricante del dispositivo que dependen desystem/code/include/private_filesystem_config.h
para las estructuras de archivos o directorios, o defs_config
, deben agregar dependencias de la bibliotecalibcutils
. - Se requieren copias de la rama privada del fabricante del dispositivo de
system/core/include/private/android_filesystem_config.h
con contenido adicional en los destinos existentes para migrar adevice/vendor/device/android_filesystem_config.h
. - Se reserva el derecho de aplicar controles de acceso obligatorio (MAC) de SELinux a los archivos de configuración del sistema de destino. Las implementaciones que incluyen ejecutables de destino personalizados con
fs_config()
deben garantizar el acceso.