Este artículo cubre cómo se construye la política SELinux. La política de SELinux se construye a partir de la combinación de la política central de AOSP (plataforma) y la política específica del dispositivo (proveedor). El flujo de compilación de políticas de SELinux para Android 4.4 hasta Android 7.0 fusionó todos los fragmentos de política y luego generó archivos monolíticos en el directorio raíz. Esto significaba que los proveedores de SoC y fabricantes de ODM modificaban boot.img
(para dispositivos que no son A/B) o system.img
(para dispositivos A/B) cada vez que se modificaba la política.
En Android 8.0 y versiones posteriores, la política de plataforma y proveedor se crea por separado. Los SOC y OEM pueden actualizar sus partes de la política, crear sus imágenes (como vendor.img
y boot.img
) y luego actualizar esas imágenes independientemente de las actualizaciones de la plataforma.
Sin embargo, como los archivos de políticas SELinux modularizados se almacenan en particiones /vendor
, el proceso init
debe montar las particiones del sistema y del proveedor antes para poder leer los archivos SELinux de esas particiones y fusionarlos con los archivos principales de SELinux en el directorio del sistema (antes de cargarlos en el núcleo).
Archivos fuente
La lógica para construir SELinux está en estos archivos:
-
external/selinux
: Proyecto SELinux externo, utilizado para crear utilidades de línea de comandos HOST para compilar políticas y etiquetas de SELinux.-
external/selinux/libselinux
: Android usa solo un subconjunto del proyectolibselinux
externo junto con algunas personalizaciones específicas de Android. Para obtener más información, consulteexternal/selinux/README.android
. -
external/selinux/libsepol
: -
external/selinux/checkpolicy
: compilador de políticas de SELinux (ejecutables del host:checkpolicy
,checkmodule
ydispol
). Depende delibsepol
.
-
-
system/sepolicy
: Configuraciones de políticas principales de Android SELinux, incluidos contextos y archivos de políticas. La principal lógica de compilación de sepolicy también se encuentra aquí (system/sepolicy/Android.mk
).
Para obtener más detalles sobre los archivos en system/sepolicy
Implementación de SELinux .
Android 7.0 y anteriores
Esta sección cubre cómo se construye la política SELinux en Android 7.x y versiones anteriores.
Construyendo la política SELinux
La política SELinux se crea combinando la política central de AOSP con personalizaciones específicas del dispositivo. Luego, la política combinada se pasa al compilador de políticas y a varios verificadores. La personalización específica del dispositivo se realiza a través de la variable BOARD_SEPOLICY_DIRS
definida en el archivo Boardconfig.mk
específico del dispositivo. Esta variable de compilación global contiene una lista de directorios que especifican el orden en el que buscar archivos de políticas adicionales.
Por ejemplo, un proveedor de SoC y un ODM podrían agregar cada uno un directorio, uno para las configuraciones específicas de SoC y otro para las configuraciones específicas del dispositivo, para generar las configuraciones finales de SELinux para un dispositivo determinado:
-
BOARD_SEPOLICY_DIRS += device/ SOC /common/sepolicy
-
BOARD_SEPOLICY_DIRS += device/ SoC / DEVICE /sepolicy
El contenido de los archivos file_contexts en system/sepolicy
y BOARD_SEPOLICY_DIRS
se concatenan para generar file_contexts.bin
en el dispositivo:
El archivo sepolicy
consta de varios archivos fuente:
- El
policy.conf
texto sin formato se genera concatenandosecurity_classes
,initial_sids
, archivos*.te
,genfs_contexts
yport_contexts
en ese orden. - Para cada archivo (como
security_classes
), su contenido es la concatenación de los archivos con el mismo nombre ensystem/sepolicy/
yBOARDS_SEPOLICY_DIRS
. -
policy.conf
se envía al compilador SELinux para verificar la sintaxis y se compila en formato binario comosepolicy
en el dispositivo.
Archivos SELinux
Después de la compilación, los dispositivos Android que ejecutan 7.x y versiones anteriores suelen contener los siguientes archivos relacionados con SELinux:
-
selinux_version
- sepolicy: salida binaria después de combinar archivos de políticas (como,
security_classes
,initial_sids
y*.te
). -
file_contexts
-
property_contexts
-
seapp_contexts
-
service_contexts
-
system/etc/mac_permissions.xml
Para obtener más detalles, consulte Implementación de SELinux .
Inicialización de SELinux
Cuando el sistema arranca, SELinux está en modo permisivo (y no en modo obligatorio). El proceso de inicio realiza las siguientes tareas:
- Carga archivos
sepolicy
desde ramdisk al kernel a través de/sys/fs/selinux/load
. - Cambia SELinux al modo obligatorio.
- Ejecuta
re-exec()
para aplicar la regla de dominio SELinux a sí mismo.
Para acortar el tiempo de inicio, realice re-exec()
en el proceso init
lo antes posible.
Android 8.0 y superior
En Android 8.0, la política de SELinux se divide en componentes de plataforma y proveedor para permitir actualizaciones independientes de la política de plataforma/proveedor manteniendo la compatibilidad.
La política de plataforma se divide a su vez en partes de plataforma privada y plataforma pública para exportar tipos y atributos específicos a los redactores de políticas de proveedores. Se garantiza que los tipos/atributos públicos de la plataforma se mantendrán como API estables para una versión de plataforma determinada. La compatibilidad con los tipos/atributos públicos de la plataforma anterior se puede garantizar para varias versiones utilizando archivos de mapeo de plataforma.
Plataforma de política pública
La plataforma public sepolicy incluye todo lo definido en system/sepolicy/public
. La plataforma puede asumir que los tipos y atributos definidos en la política pública son API estables para una versión de plataforma determinada. Esto forma parte de la política de seguridad que se exporta por plataforma en la que los desarrolladores de políticas del proveedor (es decir, del dispositivo) pueden escribir políticas adicionales específicas del dispositivo.
Los tipos tienen versiones de acuerdo con la versión de la política en la que se escriben los archivos del proveedor, definida por la variable de compilación PLATFORM_SEPOLICY_VERSION
. La política pública versionada luego se incluye con la política del proveedor y (en su forma original) en la política de la plataforma. Por lo tanto, la política final incluye la política de plataforma privada, la política pública de la plataforma actual, la política específica del dispositivo y la política pública versionada correspondiente a la versión de la plataforma en la que se escribió la política del dispositivo.
Plataforma de política privada.
La política privada de la plataforma incluye todo lo definido en /system/sepolicy/private
. Esta parte de la política establece tipos, permisos y atributos exclusivos de la plataforma necesarios para la funcionalidad de la plataforma. Estos no se exportan a los redactores de políticas de vendor/device
. Los redactores de políticas que no pertenecen a la plataforma no deben escribir sus extensiones de políticas basándose en tipos/atributos/reglas definidas en la política privada de la plataforma. Además, estas reglas pueden modificarse o desaparecer como parte de una actualización exclusiva del marco.
Mapeo privado de plataforma
El mapeo privado de la plataforma incluye declaraciones de políticas que mapean los atributos expuestos en la política pública de la plataforma de las versiones anteriores de la plataforma con los tipos concretos utilizados en la política pública de la plataforma actual. Esto garantiza que la política del proveedor escrita en función de los atributos públicos de la plataforma de las versiones anteriores de la política pública de la plataforma continúe funcionando. El control de versiones se basa en la variable de compilación PLATFORM_SEPOLICY_VERSION
establecida en AOSP para una versión de plataforma determinada. Existe un archivo de mapeo separado para cada versión de plataforma anterior a partir de la cual se espera que esta plataforma acepte la política del proveedor. Para obtener más detalles, consulte Compatibilidad .
Android 11 y superior
system_ext y política de producto
En Android 11, se agregan la política system_ext y la política de producto. Al igual que la política de plataforma, la política system_ext y la política de producto se dividen en política pública y política privada.
La política pública se exporta al proveedor. Los tipos y atributos se convierten en API estables y la política del proveedor puede hacer referencia a tipos y atributos en la política pública. Los tipos se versionan según PLATFORM_SEPOLICY_VERSION
y la política versionada se incluye en la política del proveedor. La política original se incluye en cada una de las particiones system_ext y product.
La política privada contiene tipos, permisos y atributos exclusivos de system_ext y de producto necesarios para la funcionalidad de system_ext y de las particiones de producto. La política privada es invisible para el proveedor, lo que implica que estas reglas son internas y pueden modificarse.
system_ext y mapeo de productos
system_ext y product pueden exportar sus tipos públicos designados al proveedor. Sin embargo, la responsabilidad de mantener la compatibilidad es de cada socio. Para mayor compatibilidad, los socios pueden proporcionar sus propios archivos de mapeo que asignan los atributos versionados de versiones anteriores a tipos concretos utilizados en la política pública actual.
- Para instalar un archivo de mapeo para system_ext, coloque un archivo cil que contenga la información de mapeo deseada en
{SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil
y luego agreguesystem_ext_{ver}.cil
aPRODUCT_PACKAGES
. - Para instalar un archivo de mapeo para el producto, coloque un archivo cil que contenga la información de mapeo deseada en
{PRODUCT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil
y luego agregueproduct_{ver}.cil
aPRODUCT_PACKAGES
. Consulte un ejemplo que agrega un archivo de mapeo de la partición del producto del dispositivo Redbull. - Conversión de políticas al formato de lenguaje intermedio común (CIL) de SELinux, específicamente:
- política de plataforma pública (sistema + system_ext + producto)
- política pública + privada combinada
- público + proveedor y política
BOARD_SEPOLICY_DIRS
- Versionar la política proporcionada por el público como parte de la política del proveedor. Se realiza utilizando la política CIL pública producida para informar a la política pública + proveedor +
BOARD_SEPOLICY_DIRS
combinada sobre qué partes deben convertirse en atributos que se vincularán a la política de la plataforma. - Crear un archivo de mapeo que vincule la plataforma y las partes del proveedor. Inicialmente, esto simplemente vincula los tipos de la política pública con los atributos correspondientes en la política del proveedor; Más adelante también proporcionará la base para el archivo mantenido en futuras versiones de la plataforma, lo que permitirá la compatibilidad con la política del proveedor dirigida a esta versión de la plataforma.
- Combinar archivos de políticas (describir soluciones precompiladas y en el dispositivo).
- Combine mapeo, plataforma y política de proveedores.
- Compile el archivo de política binaria de salida.
- Tanto
/system/etc/selinux/plat_sepolicy_and_mapping.sha256
como/{partition}/etc/selinux/precompiled_sepolicy.plat_sepolicy_and_mapping.sha256
existen y son idénticos. - Tanto
/system_ext/etc/selinux/system_ext_sepolicy_and_mapping.sha256
como/{partition}/etc/selinux/precompiled_sepolicy.system_ext_sepolicy_and_mapping.sha256
no existen. O ambos existen y son idénticos. - Tanto
/product/etc/selinux/product_sepolicy_and_mapping.sha256
como/{partition}/etc/selinux/precompiled_sepolicy.product_sepolicy_and_mapping.sha256
no existen. O ambos existen y son idénticos.
Construyendo la política SELinux
La política SELinux en Android 8.0 se crea combinando piezas de /system
y /vendor
. La lógica para configurar esto adecuadamente está en /platform/system/sepolicy/Android.mk
.
La política existe en las siguientes ubicaciones:
Ubicación | Contiene |
---|---|
system/sepolicy/public | La API de sepolicy de la plataforma |
system/sepolicy/private | Detalles de implementación de la plataforma (los proveedores pueden ignorarlos) |
system/sepolicy/vendor | Archivos de políticas y contexto que los proveedores pueden usar (los proveedores pueden ignorarlos si lo desean) |
BOARD_SEPOLICY_DIRS | Política del proveedor |
BOARD_ODM_SEPOLICY_DIRS (Android 9 y superior) | Política Odm |
SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS (Android 11 y superior) | API de política de System_ext |
SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS (Android 11 y superior) | Detalles de implementación de System_ext (los proveedores pueden ignorarlos) |
PRODUCT_PUBLIC_SEPOLICY_DIRS (Android 11 y superior) | API de política de seguridad del producto |
PRODUCT_PRIVATE_SEPOLICY_DIRS (Android 11 y superior) | Detalles de implementación del producto (los proveedores pueden ignorarlos) |
El sistema de compilación toma esta política y produce componentes de política de sistema, system_ext, producto, proveedor y odm en la partición correspondiente. Los pasos incluyen:
Política SELinux precompilada
Antes de que init
active SELinux, init
reúne todos los archivos CIL de las particiones ( system
, system_ext
, product
, vendor
y odm
) y los compila en una política binaria, el formato que se puede cargar en el kernel. Como la compilación lleva tiempo (normalmente entre 1 y 2 segundos), los archivos CIL se precompilan en el momento de la compilación y se colocan en /vendor/etc/selinux/precompiled_sepolicy
o /odm/etc/selinux/precompiled_sepolicy
, junto con los hash sha256. de los archivos CIL de entrada. En tiempo de ejecución, init
comprueba si alguno de los archivos de políticas se ha actualizado comparando los hashes. Si nada ha cambiado, init
carga la política precompilada. Si no, init
compila sobre la marcha y lo usa en lugar del precompilado.
Más específicamente, se utiliza una política precompilada si se cumplen todas las condiciones siguientes. Aquí, {partition}
representa la partición donde existe la política precompilada: vendor
u odm
.
Si alguno de ellos difiere, init
vuelve a la ruta de compilación del dispositivo. Consulte system/core/init/selinux.cpp
para obtener más detalles.