Este artículo describe cómo Android maneja los problemas de compatibilidad de políticas con las plataformas OTA, donde la configuración de SELinux de la nueva plataforma puede diferir de la configuración de SELinux del proveedor anterior.
El diseño de políticas SELinux basado en Treble considera una distinción binaria entre plataforma y política de proveedor ; El esquema se vuelve más complicado si las particiones de proveedores generan dependencias, como platform
< vendor
< oem
.
En Android 8.0 y superiores, la política global de SELinux se divide en componentes públicos y privados. Los componentes públicos consisten en la política y la infraestructura asociada, que se garantiza que estarán disponibles para una versión de plataforma. Esta política se expondrá a los redactores de políticas de los proveedores para permitirles crear un archivo de políticas de proveedores que, cuando se combina con la política proporcionada por la plataforma, da como resultado una política completamente funcional para un dispositivo.
- Para el control de versiones, la política pública de plataforma exportada se escribirá como atributos .
- Para facilitar la redacción de políticas, los tipos exportados se transformarán en atributos versionados como parte del proceso de creación de políticas. Los tipos públicos también se pueden utilizar directamente en las decisiones de etiquetado proporcionadas por archivos de contextos de proveedores.
Android mantiene un mapeo entre los tipos concretos exportados en la política de plataforma y los atributos versionados correspondientes para cada versión de plataforma . Esto garantiza que cuando los objetos se etiquetan con un tipo, no se rompa el comportamiento garantizado por la política pública de la plataforma en una versión anterior. Esta asignación se mantiene manteniendo actualizado un archivo de asignación para cada versión de la plataforma , que mantiene la información de membresía de atributos para cada tipo exportado en la política pública.
Propiedad y etiquetado de objetos
Al personalizar la política en Android 8.0 y versiones posteriores, se debe definir claramente la propiedad de cada objeto para mantener la política de plataforma y proveedor separada. Por ejemplo, si el proveedor etiqueta /dev/foo
y la plataforma luego etiqueta /dev/foo
en una OTA posterior, habrá un comportamiento indefinido. Para SELinux, esto se manifiesta como una colisión de etiquetado. El nodo del dispositivo puede tener solo una etiqueta que se resuelve en la etiqueta que se aplique en último lugar. Como resultado:
- Los procesos que necesiten acceso a la etiqueta aplicada sin éxito perderán el acceso al recurso.
- Los procesos que obtienen acceso al archivo pueden interrumpirse porque se creó el nodo de dispositivo incorrecto.
Las propiedades del sistema también tienen potencial para colisiones de nombres que podrían resultar en un comportamiento indefinido en el sistema (así como para el etiquetado SELinux). Pueden ocurrir colisiones entre las etiquetas de plataforma y proveedor para cualquier objeto que tenga una etiqueta SELinux, incluidas propiedades, servicios, procesos, archivos y sockets. Para evitar estos problemas, defina claramente la propiedad de estos objetos.
Además de las colisiones de etiquetas, los nombres de tipos/atributos de SELinux también pueden colisionar. Una colisión de tipo/nombre de atributo siempre resultará en un error del compilador de políticas.
Espacio de nombres de tipo/atributo
SELinux no permite múltiples declaraciones del mismo tipo/atributo. La política con declaraciones duplicadas no se podrá compilar. Para evitar colisiones de tipos y nombres de atributos, todas las declaraciones de proveedores deben tener un espacio de nombres que comience con np_
.
type foo, domain; → type np_foo, domain;
Propiedad del sistema y propiedad del etiquetado de procesos.
La mejor manera de evitar colisiones de etiquetado es utilizando espacios de nombres de propiedades. Para identificar fácilmente las propiedades de la plataforma y evitar conflictos de nombres al cambiar el nombre o agregar propiedades de la plataforma exportada, asegúrese de que todas las propiedades del proveedor tengan sus propios prefijos:
Tipo de propiedad | Prefijos aceptables |
---|---|
propiedades de control | ctl.vendor. ctl.start$vendor. ctl.stop$vendor. init.svc.vendor. |
lectura-escritura | vendor. |
solo lectura | ro.vendor. ro.boot. ro.hardware. |
persistente | persist.vendor. |
Los proveedores pueden seguir usando ro.boot.*
(que proviene de la línea cmd del kernel) y ro.hardware.*
(una propiedad obvia relacionada con el hardware).
Todos los servicios de proveedor en los archivos init rc deben tener vendor.
para servicios en archivos init rc de particiones que no son del sistema. Se aplican reglas similares a las etiquetas SELinux para las propiedades del proveedor ( vendor_
para las propiedades del proveedor).
Propiedad del archivo
Prevenir colisiones de archivos es un desafío porque la política de la plataforma y del proveedor comúnmente proporciona etiquetas para todos los sistemas de archivos. A diferencia de la denominación de tipos, el espacio de nombres de los archivos no es práctico ya que muchos de ellos son creados por el núcleo. Para evitar estas colisiones, siga la guía de nombres para sistemas de archivos en esta sección. Para Android 8.0, estas son recomendaciones sin aplicación técnica. En el futuro, estas recomendaciones serán aplicadas por Vendor Test Suite (VTS).
Sistema (/sistema)
Solo la imagen del sistema debe proporcionar etiquetas para los componentes /system
a través de file_contexts
, service_contexts
, etc. Si se agregan etiquetas para los componentes /system
en la política /vendor
, es posible que no sea posible realizar una actualización OTA solo del marco.
Proveedor (/proveedor)
La política AOSP SELinux ya etiqueta partes de la partición del vendor
con la que interactúa la plataforma, lo que permite escribir reglas SELinux para que los procesos de la plataforma puedan hablar y/o acceder a partes de la partición vendor
. Ejemplos:
/vendor | Etiqueta proporcionada por la plataforma | Procesos de plataforma dependiendo de la etiqueta |
---|---|---|
/vendor(/. * )? | vendor_file | Todos los clientes HAL en framework, ueventd , etc. |
/vendor/framework(/. * )? | vendor_framework_file | dex2oat , appdomain , etc. |
/vendor/app(/. * )? | vendor_app_file | dex2oat , installd , idmap , etc. |
/vendor/overlay(/. * ) | vendor_overlay_file | system_server , zygote , idmap , etc. |
Como resultado, se deben seguir reglas específicas (aplicadas a través de neverallows
) al etiquetar archivos adicionales en la partición vendor
:
-
vendor_file
debe ser la etiqueta predeterminada para todos los archivos en la particiónvendor
. La política de la plataforma requiere esto para acceder a implementaciones HAL de paso. - Todos los nuevos
exec_types
agregados en la particiónvendor
a través del proveedor SEPolicy deben tener el atributovendor_file_type
. Esto se aplica a través de neverallows. - Para evitar conflictos con futuras actualizaciones de plataforma/marco, evite etiquetar archivos que no sean
exec_types
en la particiónvendor
. - Todas las dependencias de biblioteca para HAL del mismo proceso identificado por AOSP deben etiquetarse como
same_process_hal_file.
Procfs (/proc)
Los archivos en /proc
se pueden etiquetar usando solo la etiqueta genfscon
. En Android 7.0, tanto la política de plataforma como la del proveedor usaban genfscon
para etiquetar archivos en procfs
.
Recomendación: solo etiquetas de política de plataforma /proc
. Si los procesos vendor
necesitan acceso a archivos en /proc
que actualmente están etiquetados con la etiqueta predeterminada ( proc
), la política del proveedor no debe etiquetarlos explícitamente y, en su lugar, debe usar el tipo de proc
genérico para agregar reglas para los dominios del proveedor. Esto permite que las actualizaciones de la plataforma se adapten a futuras interfaces del kernel expuestas a través de procfs
y las etiqueten explícitamente según sea necesario.
Debugfs (/sys/kernel/debug)
Debugfs
se pueden etiquetar tanto en file_contexts
como genfscon
. En Android 7.0 a Android 10, tanto la etiqueta de plataforma como la del proveedor debugfs
.
En Android 11, no se puede acceder debugfs
ni montarlos en dispositivos de producción. Los fabricantes de dispositivos deberían eliminar debugfs
.
Tracefs (/sys/kernel/debug/tracing)
Tracefs
se pueden etiquetar tanto en file_contexts
como genfscon
. En Android 7.0, solo la plataforma etiqueta tracefs
.
Recomendación: solo la plataforma puede etiquetar tracefs
.
sysfs (/sys)
Los archivos en /sys
se pueden etiquetar usando file_contexts
y genfscon
. En Android 7.0, tanto la plataforma como el proveedor usan file_contexts
y genfscon
para etiquetar archivos en sysfs
.
Recomendación: la plataforma puede etiquetar nodos sysfs
que no sean específicos del dispositivo. De lo contrario, sólo el proveedor puede etiquetar los archivos.
tmpfs (/dev)
Los archivos en /dev
pueden etiquetarse en file_contexts
. En Android 7.0, los archivos de etiqueta de proveedor y de plataforma se encuentran aquí.
Recomendación: el proveedor puede etiquetar solo archivos en /dev/vendor
(por ejemplo, /dev/vendor/foo
, /dev/vendor/socket/bar
).
Raíces (/)
Los archivos en /
pueden etiquetarse en file_contexts
. En Android 7.0, los archivos de etiqueta de proveedor y de plataforma se encuentran aquí.
Recomendación: Sólo el sistema puede etiquetar archivos en /
.
Datos (/datos)
Los datos se etiquetan mediante una combinación de file_contexts
y seapp_contexts
.
Recomendación: no permitir el etiquetado de proveedores fuera /data/vendor
. Sólo la plataforma puede etiquetar otras partes de /data
.
Atributos de compatibilidad
La política de SELinux es una interacción entre los tipos de origen y de destino para permisos y clases de objetos específicos. Cada objeto (procesos, archivos, etc.) afectado por la política de SELinux puede tener solo un tipo, pero ese tipo puede tener múltiples atributos.
La política está escrita principalmente en términos de tipos existentes:
allow source_type target_type:target_class permission(s);
Esto funciona porque la política se redactó con conocimientos de todo tipo. Sin embargo, si la política del proveedor y la política de la plataforma utilizan tipos específicos, y la etiqueta de un objeto específico cambia solo en una de esas políticas, la otra puede contener una política que obtuvo o perdió el acceso en el que se confiaba anteriormente. Por ejemplo:
File_contexts: /sys/A u:object_r:sysfs:s0 Platform: allow p_domain sysfs:class perm; Vendor: allow v_domain sysfs:class perm;
Podría cambiarse a:
File_contexts: /sys/A u:object_r:sysfs_A:s0
Aunque la política del proveedor seguiría siendo la misma, v_domain
perdería el acceso debido a la falta de una política para el nuevo tipo sysfs_A
.
Al definir una política en términos de atributos, podemos darle al objeto subyacente un tipo que tenga un atributo correspondiente a la política tanto para la plataforma como para el código del proveedor. Esto se puede hacer para todos los tipos para crear de manera efectiva una política de atributos en la que nunca se utilicen tipos concretos. En la práctica, esto solo es necesario para las partes de la política que se superponen entre la plataforma y el proveedor, que se definen y proporcionan como política pública de plataforma que se construye como parte de la política del proveedor.
Definir la política pública como atributos versionados satisface dos objetivos de compatibilidad de políticas:
- Asegúrese de que el código del proveedor siga funcionando después de la actualización de la plataforma . Se logra agregando atributos a tipos concretos de objetos correspondientes a aquellos en los que se basa el código del proveedor, preservando el acceso.
- Capacidad para desaprobar la política . Esto se logra delineando claramente los conjuntos de políticas en atributos que se pueden eliminar tan pronto como la versión a la que corresponden ya no sea compatible. El desarrollo puede continuar en la plataforma, sabiendo que la política anterior todavía está presente en la política del proveedor y se eliminará automáticamente cuando se actualice.
Escribibilidad de políticas
Para cumplir con el objetivo de no requerir conocimiento de cambios de versión específicos para el desarrollo de políticas, Android 8.0 incluye un mapeo entre los tipos de políticas públicas de plataforma y sus atributos. El tipo foo
se asigna al atributo foo_v N
, donde N
es la versión de destino. vN
corresponde a la variable de compilación PLATFORM_SEPOLICY_VERSION
y tiene el formato MM.NN
, donde MM
corresponde al número de SDK de la plataforma y NN
es una versión específica de la política de plataforma.
Los atributos en la política pública no tienen versiones, sino que existen como una API en la que la plataforma y la política del proveedor pueden construir para mantener estable la interfaz entre las dos particiones. Tanto los redactores de políticas de plataforma como de proveedores pueden continuar redactando políticas tal como se escriben hoy.
Política pública de plataforma exportada como allow source_foo target_bar: class perm ;
se incluye como parte de la política del proveedor. Durante la compilación (que incluye la versión correspondiente) se transforma en la política que irá a la parte del proveedor del dispositivo (que se muestra en el lenguaje intermedio común (CIL) transformado):
(allow source_foo_vN target_bar_vN (class (perm)))
Como la política del proveedor nunca va por delante de la plataforma, no debería preocuparse por las versiones anteriores. Sin embargo, la política de la plataforma necesitará saber qué tan atrás está la política del proveedor, incluir atributos para sus tipos y establecer la política correspondiente a los atributos versionados.
Diferencias de política
La creación automática de atributos agregando _v N
al final de cada tipo no hace nada sin asignar atributos a tipos en las diferencias de versión. Android mantiene un mapeo entre versiones para atributos y un mapeo de tipos para esos atributos. Esto se hace en los archivos de mapeo antes mencionados con declaraciones, como (CIL):
(typeattributeset foo_vN (foo))
Actualizaciones de plataforma
La siguiente sección detalla escenarios para actualizaciones de plataforma.
Mismos tipos
Este escenario ocurre cuando un objeto no cambia las etiquetas en las versiones de la política. Esto es lo mismo para los tipos de origen y de destino y se puede ver con /dev/binder
, que está etiquetado como binder_device
en todas las versiones. Se representa en la política transformada como:
binder_device_v1 … binder_device_vN
Al actualizar desde v1
→ v2
, la política de plataforma debe contener:
type binder_device; -> (type binder_device) (in CIL)
En el archivo de mapeo v1 (CIL):
(typeattributeset binder_device_v1 (binder_device))
En el archivo de mapeo v2 (CIL):
(typeattributeset binder_device_v2 (binder_device))
En la política de proveedor v1 (CIL):
(typeattribute binder_device_v1) (allow binder_device_v1 …)
En la política de proveedor v2 (CIL):
(typeattribute binder_device_v2) (allow binder_device_v2 …)
Nuevos tipos
Este escenario ocurre cuando la plataforma ha agregado un nuevo tipo, lo que puede ocurrir al agregar nuevas funciones o durante el endurecimiento de políticas.
- Nueva caracteristica . Cuando el tipo etiqueta un objeto que anteriormente no existía (como un nuevo proceso de servicio), el código del proveedor no interactuó previamente con él directamente, por lo que no existe una política correspondiente. El nuevo atributo correspondiente al tipo no tiene un atributo en la versión anterior y, por lo tanto, no necesitaría una entrada en el archivo de mapeo destinado a esa versión.
- Endurecimiento de políticas . Cuando el tipo representa el endurecimiento de políticas, el nuevo atributo de tipo debe vincularse nuevamente a una cadena de atributos correspondientes al anterior (similar al ejemplo anterior que cambia
/sys/A
desysfs
asysfs_A
). El código del proveedor se basa en una regla que permite el acceso asysfs
y debe incluir esa regla como un atributo del nuevo tipo.
Al actualizar desde v1
→ v2
, la política de plataforma debe contener:
type sysfs_A; -> (type sysfs_A) (in CIL) type sysfs; (type sysfs) (in CIL)
En el archivo de mapeo v1 (CIL):
(typeattributeset sysfs_v1 (sysfs sysfs_A))
En el archivo de mapeo v2 (CIL):
(typeattributeset sysfs_v2 (sysfs)) (typeattributeset sysfs_A_v2 (sysfs_A))
En la política de proveedor v1 (CIL):
(typeattribute sysfs_v1) (allow … sysfs_v1 …)
En la política de proveedor v2 (CIL):
(typeattribute sysfs_A_v2) (allow … sysfs_A_v2 …) (typeattribute sysfs_v2) (allow … sysfs_v2 …)
Tipos eliminados
Este (raro) escenario ocurre cuando se elimina un tipo, lo que puede ocurrir cuando el objeto subyacente:
- Permanece pero recibe una etiqueta diferente.
- Se retira por la plataforma.
Durante la flexibilización de la política, se elimina un tipo y el objeto etiquetado con ese tipo recibe una etiqueta diferente ya existente. Esto representa una fusión de asignaciones de atributos: el código del proveedor aún debe poder acceder al objeto subyacente mediante el atributo que solía poseer, pero el resto del sistema ahora debe poder acceder a él con su nuevo atributo.
Si el atributo al que se ha cambiado es nuevo, entonces el reetiquetado es el mismo que en el caso del nuevo tipo, excepto que cuando se utiliza una etiqueta existente, la adición del nuevo tipo del atributo antiguo provocaría que otros objetos también se etiqueten con este tipo. para ser nuevamente accesible. Esto es esencialmente lo que hace la plataforma y se considera una compensación aceptable para mantener la compatibilidad.
(typeattribute sysfs_v1) (allow … sysfs_v1 …)
Ejemplo de versión 1: colapso de tipos (eliminando sysfs_A)
Al actualizar desde v1
→ v2
, la política de plataforma debe contener:
type sysfs; (type sysfs) (in CIL)
En el archivo de mapeo v1 (CIL):
(typeattributeset sysfs_v1 (sysfs)) (type sysfs_A) # in case vendors used the sysfs_A label on objects (typeattributeset sysfs_A_v1 (sysfs sysfs_A))
En el archivo de mapeo v2 (CIL):
(typeattributeset sysfs_v2 (sysfs))
En la política de proveedor v1 (CIL):
(typeattribute sysfs_A_v1) (allow … sysfs_A_v1 …) (typeattribute sysfs_v1) (allow … sysfs_v1 …)
En la política de proveedor v2 (CIL):
(typeattribute sysfs_v2) (allow … sysfs_v2 …)
Ejemplo de versión 2: eliminación completa (tipo foo)
Al actualizar desde v1
→ v2
, la política de plataforma debe contener:
# nothing - we got rid of the type
En el archivo de mapeo v1 (CIL):
(type foo) #needed in case vendors used the foo label on objects (typeattributeset foo_v1 (foo))
En el archivo de mapeo v2 (CIL):
# nothing - get rid of it
En la política de proveedor v1 (CIL):
(typeattribute foo_v1) (allow foo …) (typeattribute sysfs_v1) (allow sysfs_v1 …)
En la política de proveedor v2 (CIL):
(typeattribute sysfs_v2) (allow sysfs_v2 …)
Nueva clase/permisos
Este escenario ocurre cuando una actualización de la plataforma introduce nuevos componentes de política que no existen en versiones anteriores. Por ejemplo, cuando Android agregó el administrador de objetos servicemanager
que creó los permisos para agregar, buscar y enumerar, los demonios proveedores que querían registrarse con el servicemanager
necesitaban permisos que no estaban disponibles. En Android 8.0, sólo la política de plataforma puede agregar nuevas clases y permisos.
Para permitir que todos los dominios que podrían haber sido creados o ampliados por la política del proveedor utilicen la nueva clase sin obstáculos, la política de la plataforma debe incluir una regla similar a:
allow {domain -coredomain} *:new_class perm;
Esto puede incluso requerir una política que permita el acceso a todos los tipos de interfaz (política pública), para garantizar que la imagen del proveedor obtenga acceso. Si esto da como resultado una política de seguridad inaceptable (como puede ocurrir con los cambios del administrador de servicios), se podría forzar una actualización del proveedor.
Clase/permisos eliminados
Este escenario ocurre cuando se elimina un administrador de objetos (como el administrador de objetos ZygoteConnection
) y no debería causar problemas. La clase y los permisos del administrador de objetos podrían permanecer definidos en la política hasta que la versión del proveedor ya no los use. Esto se hace agregando las definiciones al archivo de mapeo correspondiente.
Personalización de proveedores para tipos nuevos/reetiquetados
Los nuevos tipos de proveedores son el núcleo del desarrollo de políticas de proveedores, ya que son necesarios para describir nuevos procesos, binarios, dispositivos, subsistemas y datos almacenados. Como tal, es imperativo permitir la creación de tipos definidos por el proveedor.
Como la política de proveedor es siempre la más antigua del dispositivo, no es necesario convertir automáticamente todos los tipos de proveedores en atributos de la política. La plataforma no depende de nada etiquetado en la política del proveedor porque no tiene conocimiento de ello; sin embargo, la plataforma proporcionará los atributos y tipos públicos que utiliza para interactuar con objetos etiquetados con estos tipos (como domain
, sysfs_type
, etc.). Para que la plataforma continúe interactuando correctamente con estos objetos, los atributos y tipos deben aplicarse adecuadamente y es posible que sea necesario agregar reglas específicas a los dominios personalizables (como init
).
Cambios de atributos para Android 9
Los dispositivos que se actualizan a Android 9 pueden usar los siguientes atributos, pero los dispositivos que se inician con Android 9 no deben hacerlo.
Atributos del infractor
Android 9 incluye estos atributos relacionados con el dominio:
-
data_between_core_and_vendor_violators
. Atributo para todos los dominios que violan el requisito de no compartir archivos por ruta entrevendor
ycoredomains
. Los procesos de plataforma y proveedor no deben utilizar archivos en disco para comunicarse (ABI inestable). Recomendación:- El código del proveedor debe usar
/data/vendor
. - El sistema no debe usar
/data/vendor
.
- El código del proveedor debe usar
-
system_executes_vendor_violators
. Atributo para todos los dominios del sistema (excepto los dominiosinit
yshell domains
) que violan el requisito de no ejecutar archivos binarios del proveedor. La ejecución de archivos binarios de proveedores tiene una API inestable. La plataforma no debería ejecutar archivos binarios del proveedor directamente. Recomendación:- Estas dependencias de plataforma en los binarios de los proveedores deben estar detrás de los HAL HIDL.
O
-
coredomains
que necesitan acceso a los archivos binarios del proveedor deben moverse a la partición del proveedor y, por lo tanto, dejar de sercoredomain
.
- Estas dependencias de plataforma en los binarios de los proveedores deben estar detrás de los HAL HIDL.
Atributos que no son de confianza
Las aplicaciones que no son de confianza y que alojan código arbitrario no deberían tener acceso a los servicios de HwBinder, excepto aquellas que se consideran suficientemente seguras para acceder desde dichas aplicaciones (consulte los servicios seguros a continuación). Las dos razones principales para esto son:
- Los servidores HwBinder no realizan autenticación de cliente porque HIDL actualmente no expone la información UID de la persona que llama. Incluso si HIDL expusiera dichos datos, muchos servicios de HwBinder operan a un nivel inferior al de las aplicaciones (como HAL) o no deben depender de la identidad de la aplicación para su autorización. Por lo tanto, para estar seguros, la suposición predeterminada es que cada servicio HwBinder trata a todos sus clientes como igualmente autorizados para realizar las operaciones ofrecidas por el servicio.
- Los servidores HAL (un subconjunto de servicios HwBinder) contienen código con una mayor tasa de incidencia de problemas de seguridad que los componentes
system/core
y tienen acceso a las capas inferiores de la pila (hasta el hardware), lo que aumenta las oportunidades para eludir el modelo de seguridad de Android. .
Servicios seguros
Los servicios seguros incluyen:
-
same_process_hwservice
. Estos servicios (por definición) se ejecutan en el proceso del cliente y, por lo tanto, tienen el mismo acceso que el dominio del cliente en el que se ejecuta el proceso. -
coredomain_hwservice
. Estos servicios no presentan riesgos asociados con la razón #2. -
hal_configstore_ISurfaceFlingerConfigs
. Este servicio está diseñado específicamente para ser utilizado por cualquier dominio. -
hal_graphics_allocator_hwservice
. Estas operaciones también las ofrece el serviciosurfaceflinger
Binder, al que las aplicaciones pueden acceder. -
hal_omx_hwservice
. Esta es una versión HwBinder del serviciomediacodec
Binder, al que las aplicaciones pueden acceder. -
hal_codec2_hwservice
. Esta es una versión más nueva dehal_omx_hwservice
.
Atributos utilizables
Todos hwservices
que no se consideran seguros tienen el atributo untrusted_app_visible_hwservice
. Los servidores HAL correspondientes tienen el atributo untrusted_app_visible_halserver
. Los dispositivos que se inician con Android 9 NO DEBEN utilizar ningún atributo untrusted
.
Recomendación:
- En cambio, las aplicaciones que no son de confianza deberían comunicarse con un servicio del sistema que se comunique con el proveedor HIDL HAL. Por ejemplo, las aplicaciones pueden comunicarse con
binderservicedomain
y luegomediaserver
(que es unbinderservicedomain
) a su vez habla conhal_graphics_allocator
.O
- Las aplicaciones que necesitan acceso directo a los HAL
vendor
deben tener su propio dominio de política de seguridad definido por el proveedor.
Pruebas de atributos de archivos
Android 9 incluye pruebas de tiempo de compilación que garantizan que todos los archivos en ubicaciones específicas tengan los atributos adecuados (por ejemplo, todos los archivos en sysfs
tengan el atributo sysfs_type
requerido).
Plataforma-política pública
La política pública de plataforma es el núcleo para ajustarse al modelo de arquitectura de Android 8.0 sin simplemente mantener la unión de las políticas de plataforma de v1 y v2. Los proveedores están expuestos a un subconjunto de políticas de plataforma que contiene tipos y atributos utilizables y reglas sobre esos tipos y atributos que luego pasan a formar parte de la política de proveedores (es decir, vendor_sepolicy.cil
).
Los tipos y reglas se traducen automáticamente en la política generada por el proveedor a attribute_v N
de modo que todos los tipos proporcionados por la plataforma sean atributos versionados (sin embargo, los atributos no están versionados). La plataforma es responsable de mapear los tipos concretos que proporciona en los atributos apropiados para garantizar que la política del proveedor continúe funcionando y que se incluyan las reglas proporcionadas para una versión particular. La combinación de política pública de plataforma y política de proveedor satisface el objetivo del modelo de arquitectura de Android 8.0 de permitir compilaciones de plataforma y proveedor independientes.
Mapeo de cadenas de atributos
Cuando se utilizan atributos para asignar a versiones de políticas, un tipo se asigna a uno o varios atributos, lo que garantiza que los objetos etiquetados con el tipo sean accesibles a través de atributos correspondientes a sus tipos anteriores.
Mantener el objetivo de ocultar la información de la versión al redactor de políticas significa generar automáticamente los atributos versionados y asignarlos a los tipos apropiados. En el caso común de tipos estáticos, esto es sencillo: type_foo
se asigna a type_foo_v1
.
Para un cambio de etiqueta de objeto como sysfs
→ sysfs_A
o mediaserver
→ audioserver
, la creación de esta asignación no es trivial (y se describe en los ejemplos anteriores). Los mantenedores de políticas de plataforma deben determinar cómo crear el mapeo en los puntos de transición para los objetos, lo que requiere comprender la relación entre los objetos y sus etiquetas asignadas y determinar cuándo ocurre esto. Para lograr compatibilidad con versiones anteriores, esta complejidad debe gestionarse en el lado de la plataforma, que es la única partición que puede actualizarse.
versión uprevs
Para simplificar, la plataforma Android lanza una versión de política cuando se corta una nueva rama de lanzamiento. Como se describió anteriormente, el número de versión está contenido en PLATFORM_SEPOLICY_VERSION
y tiene el formato MM.nn
, donde MM
corresponde al valor del SDK y nn
es un valor privado mantenido en /platform/system/sepolicy.
Por ejemplo, 19.0
para Kitkat, 21.0
para Lollipop, 22.0
para Lollipop-MR1, 23.0
para Marshmallow, 24.0
para Nougat, 25.0
para Nougat-MR1, 26.0
para Oreo, 27.0
para Oreo-MR1 y 28.0
para Android 9. Uprevs no siempre números enteros. Por ejemplo, si un aumento de MR en una versión requiere un cambio incompatible en system/sepolicy/public
pero no un aumento de API, entonces esa versión de sepolicy podría ser: vN.1
. La versión presente en una rama de desarrollo es 10000.0
que nunca se usará en dispositivos de envío.
Android puede desaprobar la versión más antigua al actualizarla. Para obtener información sobre cuándo desaprobar una versión, Android puede recopilar la cantidad de dispositivos con políticas de proveedores que ejecutan esa versión de Android y aún reciben actualizaciones importantes de la plataforma. Si el número es inferior a un determinado umbral, esa versión queda obsoleta.
Impacto en el rendimiento de múltiples atributos
Como se describe en https://github.com/SELinuxProject/cil/issues/9 , una gran cantidad de atributos asignados a un tipo generan problemas de rendimiento en caso de que se pierda la caché de políticas.
Se confirmó que esto era un problema en Android, por lo que se realizaron cambios en Android 8.0 para eliminar los atributos agregados a la política por el compilador de políticas, así como para eliminar los atributos no utilizados. Estos cambios resolvieron las regresiones de desempeño.
System_ext política pública y de producto
A partir de Android 11, las particiones system_ext y product pueden exportar sus tipos públicos designados a la partición del proveedor. Al igual que la política pública de la plataforma, el proveedor utiliza tipos y reglas traducidas automáticamente a los atributos versionados, por ejemplo, de type
a type_ N
, donde N
es la versión de la plataforma con la que se construye la partición del proveedor.
Cuando las particiones system_ext y product se basan en la misma versión de plataforma N
, el sistema de compilación genera archivos de mapeo base para system_ext/etc/selinux/mapping/ N .cil
y product/etc/selinux/mapping/ N .cil
, que contienen identidad asignaciones de type
a type_ N
. El proveedor puede acceder type
con el atributo versionado type_ N
En caso de que solo se actualicen las particiones system_ext y del producto, digamos de N
a N+1
(o posterior), mientras el proveedor permanece en N
, el proveedor puede perder el acceso a los tipos de particiones system_ext y del producto. Para evitar roturas, las particiones system_ext y product deben proporcionar archivos de mapeo de tipos concretos a atributos type_ N
. Cada socio es responsable de mantener los archivos de mapeo, si van a admitir N
proveedores con N+1
(o posterior) system_ext y particiones de producto.
Para ello, se espera que los socios:
- Copie los archivos de mapeo base generados desde
N
system_ext y las particiones del producto a su árbol de origen. - Modifique los archivos de mapeo según sea necesario.
- Instale los archivos de asignación en
N+1
(o posterior) system_ext y particiones del producto.
Por ejemplo, supongamos que N
system_ext tiene un tipo público llamado foo_type
. Entonces system_ext/etc/selinux/mapping/ N .cil
en la partición N
system_ext se verá así:
(typeattributeset foo_type_N (foo_type)) (expandtypeattribute foo_type_N true) (typeattribute foo_type_N)
Si bar_type
se agrega a N+1
system_ext, y si bar_type
debe asignarse a foo_type
para N
proveedor, N .cil
se puede actualizar desde
(typeattributeset foo_type_N (foo_type))
a
(typeattributeset foo_type_N (foo_type bar_type))
y luego se instala en la partición N+1
system_ext. N
proveedores pueden continuar accediendo a foo_type
y bar_type
de N+1
system_ext.
Etiquetado de contextos SELinux
Para respaldar la distinción entre plataforma y política de proveedor, el sistema crea archivos de contexto SELinux de manera diferente para mantenerlos separados.
Contextos de archivos
Android 8.0 introdujo los siguientes cambios para file_contexts
:
- Para evitar una sobrecarga adicional de compilación en el dispositivo durante el arranque,
file_contexts
deja de existir en formato binario. En cambio, son archivos de texto de expresión regular legibles, como{property, service}_contexts
(como eran antes de 7.0). - Los
file_contexts
se dividen entre dos archivos:-
plat_file_contexts
-
file_context
de la plataforma Android que no tiene etiquetas específicas del dispositivo, excepto para etiquetar partes de la partición/vendor
que deben etiquetarse con precisión para garantizar el funcionamiento adecuado de los archivos de política. - Debe residir en la partición
system
en/system/etc/selinux/plat_file_contexts
en el dispositivo y ser cargado porinit
al inicio junto con elfile_context
del proveedor.
-
-
vendor_file_contexts
-
file_context
específico del dispositivo creado combinandofile_contexts
que se encuentran en los directorios señalados porBOARD_SEPOLICY_DIRS
en los archivosBoardconfig.mk
del dispositivo. - Debe instalarse en
/vendor/etc/selinux/vendor_file_contexts
en la particiónvendor
y cargarse medianteinit
al inicio junto con elfile_context
de la plataforma.
-
-
Contextos de propiedad
En Android 8.0, property_contexts
se divide en dos archivos:
-
plat_property_contexts
-
property_context
de la plataforma Android que no tiene etiquetas específicas del dispositivo. - Debe residir en la partición
system
en/system/etc/selinux/plat_property_contexts
y ser cargado porinit
al inicio junto con el proveedorproperty_contexts
.
-
-
vendor_property_contexts
-
property_context
específico del dispositivo creado mediante la combinaciónproperty_contexts
que se encuentran en los directorios señalados porBOARD_SEPOLICY_DIRS
en los archivosBoardconfig.mk
del dispositivo. - Debe residir en la partición
vendor
en/vendor/etc/selinux/vendor_property_contexts
y debe cargarse medianteinit
al inicio junto con elproperty_context
de la plataforma.
-
Contextos de servicio
En Android 8.0, service_contexts
se divide entre los siguientes archivos:
-
plat_service_contexts
-
service_context
específico de la plataforma Android paraservicemanager
.service_context
no tiene etiquetas específicas del dispositivo. - Debe residir en la partición
system
en/system/etc/selinux/plat_service_contexts
y ser cargado porservicemanager
al inicio junto con el proveedorservice_contexts
.
-
-
vendor_service_contexts
-
service_context
específico del dispositivo creado combinandoservice_contexts
que se encuentran en los directorios señalados porBOARD_SEPOLICY_DIRS
en los archivosBoardconfig.mk
del dispositivo. - Debe residir en la partición
vendor
en/vendor/etc/selinux/vendor_service_contexts
y ser cargado porservicemanager
al inicio junto con la plataformaservice_contexts
. - Aunque
servicemanager
busca este archivo en el momento del arranque, para un dispositivoTREBLE
totalmente compatible,vendor_service_contexts
NO DEBE existir. Esto se debe a que toda interacción entrevendor
y los procesossystem
DEBE pasar porhwservicemanager
/hwbinder
.
-
-
plat_hwservice_contexts
- Plataforma Android
hwservice_context
parahwservicemanager
que no tiene etiquetas específicas del dispositivo. - Debe residir en la partición del
system
en/system/etc/selinux/plat_hwservice_contexts
yhwservicemanager
lo cargará al inicio junto convendor_hwservice_contexts
.
- Plataforma Android
-
vendor_hwservice_contexts
-
hwservice_context
específico del dispositivo creado combinandohwservice_contexts
que se encuentran en los directorios señalados porBOARD_SEPOLICY_DIRS
en los archivosBoardconfig.mk
del dispositivo. - Debe residir en la partición
vendor
en/vendor/etc/selinux/vendor_hwservice_contexts
yhwservicemanager
lo carga al inicio junto conplat_service_contexts
.
-
-
vndservice_contexts
-
service_context
específico del dispositivo paravndservicemanager
creado combinandovndservice_contexts
que se encuentran en los directorios señalados porBOARD_SEPOLICY_DIRS
enBoardconfig.mk
del dispositivo. - Este archivo debe residir en la partición
vendor
en/vendor/etc/selinux/vndservice_contexts
yvndservicemanager
lo cargará al inicio.
-
Contextos de aplicaciones marítimas
En Android 8.0, seapp_contexts
se divide en dos archivos:
-
plat_seapp_contexts
- Plataforma Android
seapp_context
que no tiene cambios específicos del dispositivo. - Debe residir en la partición del
system
en/system/etc/selinux/plat_seapp_contexts.
- Plataforma Android
-
vendor_seapp_contexts
- Extensión específica del dispositivo para la plataforma
seapp_context
creada mediante la combinación deseapp_contexts
que se encuentran en los directorios señalados porBOARD_SEPOLICY_DIRS
en los archivosBoardconfig.mk
del dispositivo. - Debe residir en la partición
vendor
en/vendor/etc/selinux/vendor_seapp_contexts
.
- Extensión específica del dispositivo para la plataforma
permisos MAC
En Android 8.0, mac_permissions.xml
se divide en dos archivos:
- Plataforma
mac_permissions.xml
- Plataforma Android
mac_permissions.xml
que no tiene cambios específicos del dispositivo. - Debe residir en la partición
system
en/system/etc/selinux/.
- Plataforma Android
-
mac_permissions.xml
sin plataforma- Extensión específica del dispositivo para la plataforma
mac_permissions.xml
creada a partir demac_permissions.xml
que se encuentra en los directorios señalados porBOARD_SEPOLICY_DIRS
en los archivosBoardconfig.mk
del dispositivo. - Debe residir en la partición
vendor
en/vendor/etc/selinux/.
- Extensión específica del dispositivo para la plataforma