Control de acceso discrecional (DAC)

Los objetos del sistema de archivos y los servicios agregados a la compilación con frecuencia necesitan separar IDs únicos, conocidos como IDs de Android (AID). Actualmente, muchos recursos, como Los archivos y servicios usan AID principales (definidos por Android) de manera innecesaria. en muchas puedes usar AID de OEM (definidos por el OEM).

Las versiones anteriores de Android (Android 7.x y versiones anteriores) ampliaban los AID mecanismo mediante un android_filesystem_config.h específico del dispositivo para especificar las capacidades del sistema de archivos o los AID de OEM personalizados. Sin embargo, no era intuitivo, ya que no admitía el uso de nombres agradables para los AID de OEM. lo que requiere que especifiques el valor numérico sin procesar para los campos de usuario y grupo sin un 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 lo que extiende las capacidades del sistema de archivos. Este nuevo método es compatible con el lo siguiente:

  • Múltiples ubicaciones de origen para los archivos de configuración (permite extensiones configuraciones de compilación).
  • Verificación de estado durante el tiempo de compilación de los valores de AID del OEM.
  • Genera un encabezado personalizado de AID de OEM que se puede usar en archivos de origen como según tus necesidades.
  • Asociación de un nombre descriptivo con el valor real de AID de OEM. Admite argumentos de cadena no numéricos para usuario y grupo, p.ej., "foo" en vez de “2901”

Entre las mejoras adicionales, se incluye la eliminación de android_ids[] array desde system/core/libcutils/include/private/android_filesystem_config.h Esta ahora existe en Bionic como un array generado de forma completamente privada, con de acceso con getpwnam() y getgrnam(). (Esto tiene el efecto secundario de producir objetos binarios estables a medida que se modifican los AID principales) Para y un archivo README con más detalles, consulta build/make/tools/fs_config

Agregar IDs de Android (AIDs)

En Android 8.0, se quitó el array android_ids[] de Android. Proyecto de código abierto (AOSP). Todos los nombres que admiten AID se generan a partir de system/core/libcutils/include/private/android_filesystem_config.h cuando se genera el array android_ids[] de Bionic. Cualquiera Las herramientas recogen define que coinciden con AID_* y * se convierte en el nombre en minúscula.

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 es se generan durante la compilación y se ponen a disposición de las interfaces que usan usuarios y grupos argumentos. Las herramientas validan que el nuevo AID no esté dentro de la APP ni el OEM. rangos; también respeta los cambios en esos rangos y debería reconfigurar los cambios o los nuevos rangos reservados por el OEM.

Configurar AID

Para habilitar el nuevo mecanismo de AID, establece TARGET_FS_CONFIG_GEN en el archivo BoardConfig.mk. Esta variable contiene una lista de reglas archivos, lo que te permite adjuntarlos según sea necesario.

Por convención, los archivos de configuración usan el nombre config.fs, pero en puedes usar cualquier nombre. Los archivos de config.fs se encuentran en Python ConfigParser ini format e incluye una sección de mayúsculas (para configurar el archivo capacidades del sistema) y una sección de AID (para configurar AID de OEM).

Configura la sección de limitaciones

La sección de mayúsculas admite la configuración archivo del sistema de archivos en los objetos del sistema de archivos de la compilación también debe ser compatible con esta funcionalidad).

Dado que ejecutar un servicio estable como raíz en Android provoca Conjunto de pruebas de compatibilidad (CTS) falla, los requisitos anteriores para retener una capacidad mientras se ejecuta un proceso o servicio implicó configurar capacidades y, luego, usar setuid/setgid a un AID adecuado para que se ejecute. Con las mayúsculas, puedes puede omitir estos requisitos y hacer que el kernel lo haga por ti. Cuando el control está a main(), tu proceso ya tiene las capacidades de recursos para que tu servicio pueda usar un grupo y un usuario no raíz (este es el para iniciar servicios con privilegios).

La sección de mayúsculas usa la siguiente sintaxis:

Sección Valor Definición
[path] La ruta del sistema de archivos que se configurará. Una ruta de acceso que termina en / se considera un dir, de lo contrario, es un archivo.

Es un error especificar varias secciones con la misma [path] en diferentes archivos. En las versiones de Python <= 3.2, el el mismo archivo puede contener secciones que anulen la sección anterior; en Python 3.2, está configurado en modo estricto.
mode Modo de archivo octal Un modo de archivo octal válido de al menos 3 dígitos. Si se especifica 3, es con el prefijo 0, se usa el modo else tal como está.
user AID_<usuario> C define para un AID válido o un nombre descriptivo (p.ej., se aceptan AID_RADIO y radio). Para definir un AID personalizado; consulta Cómo configurar en la sección AID.
group AID_<grupo> Igual que el usuario.
caps tapa* El nombre declarado en bionic/libc/kernel/uapi/linux/capability.h sin la CAP_ inicial. Se permite la combinación de mayúsculas y minúsculas. Las mayúsculas también pueden sin procesar:
  • binario (0b0101)
  • octal (0455)
  • int (42)
  • hexadecimal (0xFF)
Separa varias mayúsculas con espacios en blanco.

Para ver un ejemplo de uso, consulta Cómo usar archivos capacidades del sistema.

Configura la sección de AID

La sección de AID contiene AID de OEM y usa la siguiente sintaxis:

Sección Valor Definición
[AID_<name>] El <name> puede contener caracteres del conjunto. mayúsculas, números y guiones bajos. La versión en minúscula se usa como nombre descriptivo. El archivo de encabezado generado para incluir código utiliza el rango AID_<name>

Es un error especificar varias secciones con la misma AID_<name> (no distingue mayúsculas de minúsculas, con las mismas restricciones que [path]).

<name> debe comenzar con el nombre de una partición para garantizar para que no entre en conflicto con distintas fuentes.
value <número> Una cadena de números de estilo C válida (hex, octal, binario 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 usado en <name>. La lista de particiones válidas y sus correspondientes los rangos se definen en system/core/libcutils/include/private/android_filesystem_config.h. Las opciones son las siguientes:
  • Partición de proveedor
    • AID_OEM_RESERVED_START(2900) - AID_OEM_RESERVED_END(2999)
    • AID_OEM_RESERVED_2_START(5000) - AID_OEM_RESERVED_2_END(5999)
  • Partición del sistema
    • AID_SYSTEM_RESERVED_START(6000) - AID_SYSTEM_RESERVED_END(6499)
  • Partición ODM
    • AID_ODM_RESERVED_START(6500) - AID_ODM_RESERVED_END(6999)
  • Partición de producto
    • AID_PRODUCT_RESERVED_START(7000) - AID_PRODUCT_RESERVED_END(7499)
  • Partición de ext. sistema
    • AID_SYSTEM_EXT_RESERVED_START(7500) - AID_SYSTEM_EXT_RESERVED_END(7999)

Para ver ejemplos de uso, consulta Cómo definir OEM Nombres de AID y Cómo usar AID de OEM.

Ejemplos de uso

En los siguientes ejemplos, se detalla cómo definir y usar un AID de OEM y cómo habilitar las capacidades del sistema de archivos. Nombres de AID de OEM ([AID_name]) debe comenzar con una nombre de la partición, como “vendor_” para garantizar que no entren en conflicto con nombres del AOSP y otras particiones.

Cómo definir nombres de AID de OEM

Para definir un AID de OEM, crea un archivo config.fs y establece el valor de AID. Por ejemplo, en device/x/y/config.fs, establece la lo siguiente:

[AID_VENDOR_FOO]
value: 2900

Después de crear el archivo, configura la variable TARGET_FS_CONFIG_GEN y apúntala en BoardConfig.mk. Por ejemplo, en device/x/y/BoardConfig.mk, configura lo siguiente:

TARGET_FS_CONFIG_GEN += device/x/y/config.fs

El sistema ahora puede consumir tu AID personalizado en una compilación nueva.

Usa AID de OEM

Para usar un AID de OEM, en tu código C, incluye el oemaids_headers en tu Makefile, agregar #include "generated_oem_aid.h"; luego, comenzar a usar el archivo declarado identificadores. Por ejemplo, en my_file.c, agrega lo siguiente:

#include "generated_oem_aid.h"
…

If (ipc->uid == AID_VENDOR_FOO) {
  // Do something
...

En tu 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 descriptivos

En Android 9, puedes usar el nombre descriptivo para cualquier que admite nombres de AID. Por ejemplo:

  • En un comando chown en some/init.rc:
    chown vendor_foo /vendor/some/vendor_foo/file
    
  • En un elemento service de some/init.rc:
    service vendor_foo /vendor/bin/foo_service
        user vendor_foo
        group vendor_foo
    

Debido a que la asignación interna del nombre descriptivo al UID, la realiza /vendor/etc/passwd y /vendor/etc/group, el proveedor partición debe estar activada.

Asociar nombres descriptivos

Android 9 admite la asociación de un nombre descriptivo con el valor real de AID de OEM. Puedes usar cadenas no numéricas argumentos para usuario y grupo, es decir, "vendor_foo" en vez de “2901”

Convierte el AID en nombres descriptivos

Para OEM AID, Android 8.x requería el uso de oem_#### con getpwnam y funciones similares, como en lugares que manejan búsquedas con getpwnam (como secuencias de comandos init). En Android 9, puedes hacer lo siguiente: usa los amigos getpwnam y getgrnam en Bionic para y viceversa.

Cómo usar las capacidades del sistema de archivos

Para habilitar las capacidades del sistema de archivos, crea una sección de mayúsculas en 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 la 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, este inicia con las capacidades CAP_SYS_ADMIN y CAP_SYS_NICE sin llamadas a setuid y setgid. Además, el 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-7.x)

Android 6.0 trasladó fs_config y estructura asociada definiciones (system/core/include/private/android_filesystem_config.h) a system/core/libcutils/fs_config.c, donde podrían actualizarse o anulados por archivos binarios instalados en /system/etc/fs_config_dirs y /system/etc/fs_config_files Usa coincidencias y análisis separados reglas para directorios y archivos (que podrían usar expresiones glob adicionales) permitió que Android manejara directorios y archivos en dos tablas diferentes. Las definiciones de estructura en system/core/libcutils/fs_config.c no solo permitía la lectura del tiempo de ejecución de directorios y archivos, pero el host podía los mismos archivos durante el tiempo de compilación para construir imágenes de 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 de extensión del sistema de archivos se reemplazó por con el sistema de configuración modular presentado en Android 8.0, aún puedes usar el antiguo si así lo deseas. En las siguientes secciones, se detalla cómo generar e incluir anular archivos y configurar el sistema de archivos.

Genera archivos de anulación

Puedes generar archivos binarios alineados /system/etc/fs_config_dirs y /system/etc/fs_config_files con el Herramienta fs_config_generate en build/tools/fs_config. El La herramienta usa una función de biblioteca libcutils. (fs_config_generate()) para administrar los requisitos de DAC en un búfer y define reglas para un archivo de inclusión a fin de institucionalizar las reglas de DAC.

Para usarlo, crea un archivo de inclusión en device/vendor/device/android_filesystem_config.h que actúa como anulación. El archivo debe usar el Se definió un formato de structure fs_path_config en system/core/include/private/android_filesystem_config.h con el siguientes inicializaciones de estructura para los símbolos de directorios y archivos:

  • Para los directorios, usa android_device_dirs[].
  • Para archivos, usa android_device_files[].

Cuando no uses android_device_dirs[] y android_device_files[], puedes definir NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS y NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES (consulta las ejemplo). También puedes especificar la anulación usando TARGET_ANDROID_FILESYSTEM_CONFIG_H en la pizarra de Terraform, con un nombre base aplicado de android_filesystem_config.h

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. Sistema de compilación busca android_filesystem_config.h personalizados en $(TARGET_DEVICE_DIR), donde existe BoardConfig.mk Si este archivo existe en otro lugar, establece la variable de configuración de la placa TARGET_ANDROID_FILESYSTEM_CONFIG_H para apuntar 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:

  1. Crea el $(TARGET_DEVICE_DIR)/android_filesystem_config.h .
  2. Agrega fs_config_dirs o fs_config_files a PRODUCT_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 system/bin/glgps. daemon para agregar compatibilidad con bloqueo de activación device/vendor/device. Mantén la lo siguiente:

  • Cada entrada de la estructura es el modo, el UID, el GID, las capacidades y el nombre. system/core/include/private/android_filesystem_config.h es se incluye automáticamente para proporcionar el manifiesto #define (AID_ROOT, AID_SHELL, CAP_BLOCK_SUSPEND).
  • En la sección android_device_files[], se incluye una acción para suprimir el acceso a system/etc/fs_config_dirs cuando no se especifica, lo que sirve como protección de DAC adicional para la falta de contenido en el directorio anulaciones. Sin embargo, esta es una protección débil. si alguien tiene control sobre /system, por lo general, pueden hacer lo que quieran.
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)

Cómo migrar sistemas de archivos de versiones anteriores

Cuando migres sistemas de archivos desde Android 5.x y versiones anteriores, ten en cuenta que Android 6.x

  • Quita algunas inclusiones, estructuras y definiciones intercaladas.
  • Requiere una referencia a libcutils en lugar de ejecutarse directamente. desde system/core/include/private/android_filesystem_config.h. ejecutables privados del fabricante del dispositivo que dependen system/code/include/private_filesystem_config.h para el archivo las estructuras de directorios o fs_config deben agregar libcutils dependencias de bibliotecas.
  • Requiere copias de las ramas privadas del fabricante del dispositivo de la system/core/include/private/android_filesystem_config.h con contenido adicional en objetivos existentes para pasar a device/vendor/device/android_filesystem_config.h
  • Se reserva el derecho de aplicar Controles de acceso obligatorio (MAC) de SELinux a archivos de configuración en el sistema de destino, implementaciones que incluyen los ejecutables de destino con fs_config() deben garantizar el acceso.